1use crate::dialects::DialectType;
14use crate::expressions::{
15 BinaryOp, BooleanLiteral, Case, ConcatWs, DateTruncFunc, Expression, Literal, Null, Paren,
16 UnaryOp,
17};
18
19pub fn simplify(expression: Expression, dialect: Option<DialectType>) -> Expression {
21 let mut simplifier = Simplifier::new(dialect);
22 simplifier.simplify(expression)
23}
24
25pub fn always_true(expr: &Expression) -> bool {
27 match expr {
28 Expression::Boolean(b) => b.value,
29 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
30 let Literal::Number(n) = lit.as_ref() else {
31 unreachable!()
32 };
33 if let Ok(num) = n.parse::<f64>() {
35 num != 0.0
36 } else {
37 false
38 }
39 }
40 _ => false,
41 }
42}
43
44pub fn is_boolean_true(expr: &Expression) -> bool {
46 matches!(expr, Expression::Boolean(b) if b.value)
47}
48
49pub fn is_boolean_false(expr: &Expression) -> bool {
51 matches!(expr, Expression::Boolean(b) if !b.value)
52}
53
54pub fn always_false(expr: &Expression) -> bool {
56 is_false(expr) || is_null(expr) || is_zero(expr)
57}
58
59pub fn is_false(expr: &Expression) -> bool {
61 matches!(expr, Expression::Boolean(b) if !b.value)
62}
63
64pub fn is_null(expr: &Expression) -> bool {
66 matches!(expr, Expression::Null(_))
67}
68
69pub fn is_zero(expr: &Expression) -> bool {
71 match expr {
72 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
73 let Literal::Number(n) = lit.as_ref() else {
74 unreachable!()
75 };
76 if let Ok(num) = n.parse::<f64>() {
77 num == 0.0
78 } else {
79 false
80 }
81 }
82 _ => false,
83 }
84}
85
86pub fn is_complement(a: &Expression, b: &Expression) -> bool {
88 if let Expression::Not(not_op) = b {
89 ¬_op.this == a
90 } else {
91 false
92 }
93}
94
95pub fn bool_true() -> Expression {
97 Expression::Boolean(BooleanLiteral { value: true })
98}
99
100pub fn bool_false() -> Expression {
102 Expression::Boolean(BooleanLiteral { value: false })
103}
104
105pub fn null() -> Expression {
107 Expression::Null(Null)
108}
109
110pub fn eval_boolean_nums(op: &str, a: f64, b: f64) -> Option<Expression> {
112 let result = match op {
113 "=" | "==" => a == b,
114 "!=" | "<>" => a != b,
115 ">" => a > b,
116 ">=" => a >= b,
117 "<" => a < b,
118 "<=" => a <= b,
119 _ => return None,
120 };
121 Some(if result { bool_true() } else { bool_false() })
122}
123
124pub fn eval_boolean_strings(op: &str, a: &str, b: &str) -> Option<Expression> {
126 let result = match op {
127 "=" | "==" => a == b,
128 "!=" | "<>" => a != b,
129 ">" => a > b,
130 ">=" => a >= b,
131 "<" => a < b,
132 "<=" => a <= b,
133 _ => return None,
134 };
135 Some(if result { bool_true() } else { bool_false() })
136}
137
138pub struct Simplifier {
140 _dialect: Option<DialectType>,
141 max_iterations: usize,
142}
143
144impl Simplifier {
145 pub fn new(dialect: Option<DialectType>) -> Self {
147 Self {
148 _dialect: dialect,
149 max_iterations: 100,
150 }
151 }
152
153 pub fn simplify(&mut self, expression: Expression) -> Expression {
155 let mut current = expression;
157 for _ in 0..self.max_iterations {
158 let simplified = self.simplify_once(current.clone());
159 if expressions_equal(&simplified, ¤t) {
160 return simplified;
161 }
162 current = simplified;
163 }
164 current
165 }
166
167 fn simplify_once(&mut self, expression: Expression) -> Expression {
169 match expression {
170 Expression::And(op) => self.simplify_and(*op),
172 Expression::Or(op) => self.simplify_or(*op),
173
174 Expression::Not(op) => self.simplify_not(*op),
176
177 Expression::Add(op) => self.simplify_add(*op),
179 Expression::Sub(op) => self.simplify_sub(*op),
180 Expression::Mul(op) => self.simplify_mul(*op),
181 Expression::Div(op) => self.simplify_div(*op),
182
183 Expression::Eq(op) => self.simplify_comparison(*op, "="),
185 Expression::Neq(op) => self.simplify_comparison(*op, "!="),
186 Expression::Gt(op) => self.simplify_comparison(*op, ">"),
187 Expression::Gte(op) => self.simplify_comparison(*op, ">="),
188 Expression::Lt(op) => self.simplify_comparison(*op, "<"),
189 Expression::Lte(op) => self.simplify_comparison(*op, "<="),
190
191 Expression::Neg(op) => self.simplify_neg(*op),
193
194 Expression::Case(case) => self.simplify_case(*case),
196
197 Expression::Concat(op) => self.simplify_concat(*op),
199 Expression::ConcatWs(concat_ws) => self.simplify_concat_ws(*concat_ws),
200
201 Expression::Paren(paren) => self.simplify_paren(*paren),
203
204 Expression::DateTrunc(dt) => self.simplify_datetrunc(*dt),
206 Expression::TimestampTrunc(dt) => self.simplify_datetrunc(*dt),
207
208 other => self.simplify_children(other),
210 }
211 }
212
213 fn simplify_and(&mut self, op: BinaryOp) -> Expression {
215 let left = self.simplify_once(op.left);
216 let right = self.simplify_once(op.right);
217
218 if is_boolean_false(&left) || is_boolean_false(&right) {
221 return bool_false();
222 }
223
224 if is_zero(&left) || is_zero(&right) {
227 return bool_false();
228 }
229
230 if (is_null(&left) && is_null(&right))
234 || (is_null(&left) && is_boolean_true(&right))
235 || (is_boolean_true(&left) && is_null(&right))
236 {
237 return null();
238 }
239
240 if is_boolean_true(&left) {
242 return right;
243 }
244
245 if is_boolean_true(&right) {
247 return left;
248 }
249
250 if is_complement(&left, &right) || is_complement(&right, &left) {
252 return bool_false();
253 }
254
255 if expressions_equal(&left, &right) {
257 return left;
258 }
259
260 absorb_and_eliminate_and(left, right)
264 }
265
266 fn simplify_or(&mut self, op: BinaryOp) -> Expression {
268 let left = self.simplify_once(op.left);
269 let right = self.simplify_once(op.right);
270
271 if is_boolean_true(&left) {
273 return bool_true();
274 }
275
276 if is_boolean_true(&right) {
278 return bool_true();
279 }
280
281 if (is_null(&left) && is_null(&right))
285 || (is_null(&left) && is_boolean_false(&right))
286 || (is_boolean_false(&left) && is_null(&right))
287 {
288 return null();
289 }
290
291 if is_boolean_false(&left) {
293 return right;
294 }
295
296 if is_boolean_false(&right) {
298 return left;
299 }
300
301 if expressions_equal(&left, &right) {
303 return left;
304 }
305
306 absorb_and_eliminate_or(left, right)
310 }
311
312 fn simplify_not(&mut self, op: UnaryOp) -> Expression {
314 match &op.this {
317 Expression::Eq(inner_op) => {
319 let left = self.simplify_once(inner_op.left.clone());
320 let right = self.simplify_once(inner_op.right.clone());
321 return Expression::Neq(Box::new(BinaryOp::new(left, right)));
322 }
323 Expression::Neq(inner_op) => {
325 let left = self.simplify_once(inner_op.left.clone());
326 let right = self.simplify_once(inner_op.right.clone());
327 return Expression::Eq(Box::new(BinaryOp::new(left, right)));
328 }
329 Expression::Gt(inner_op) => {
331 let left = self.simplify_once(inner_op.left.clone());
332 let right = self.simplify_once(inner_op.right.clone());
333 return Expression::Lte(Box::new(BinaryOp::new(left, right)));
334 }
335 Expression::Gte(inner_op) => {
337 let left = self.simplify_once(inner_op.left.clone());
338 let right = self.simplify_once(inner_op.right.clone());
339 return Expression::Lt(Box::new(BinaryOp::new(left, right)));
340 }
341 Expression::Lt(inner_op) => {
343 let left = self.simplify_once(inner_op.left.clone());
344 let right = self.simplify_once(inner_op.right.clone());
345 return Expression::Gte(Box::new(BinaryOp::new(left, right)));
346 }
347 Expression::Lte(inner_op) => {
349 let left = self.simplify_once(inner_op.left.clone());
350 let right = self.simplify_once(inner_op.right.clone());
351 return Expression::Gt(Box::new(BinaryOp::new(left, right)));
352 }
353 _ => {}
354 }
355
356 let inner = self.simplify_once(op.this);
358
359 if is_null(&inner) {
361 return null();
362 }
363
364 if is_boolean_true(&inner) {
366 return bool_false();
367 }
368
369 if is_boolean_false(&inner) {
371 return bool_true();
372 }
373
374 if let Expression::Not(inner_not) = &inner {
376 return inner_not.this.clone();
377 }
378
379 Expression::Not(Box::new(UnaryOp {
380 this: inner,
381 inferred_type: None,
382 }))
383 }
384
385 fn simplify_add(&mut self, op: BinaryOp) -> Expression {
387 let left = self.simplify_once(op.left);
388 let right = self.simplify_once(op.right);
389
390 if let (Some(a), Some(b)) = (get_number(&left), get_number(&right)) {
392 return Expression::Literal(Box::new(Literal::Number((a + b).to_string())));
393 }
394
395 if is_zero(&right) {
397 return left;
398 }
399
400 if is_zero(&left) {
402 return right;
403 }
404
405 Expression::Add(Box::new(BinaryOp::new(left, right)))
406 }
407
408 fn simplify_sub(&mut self, op: BinaryOp) -> Expression {
410 let left = self.simplify_once(op.left);
411 let right = self.simplify_once(op.right);
412
413 if let (Some(a), Some(b)) = (get_number(&left), get_number(&right)) {
415 return Expression::Literal(Box::new(Literal::Number((a - b).to_string())));
416 }
417
418 if is_zero(&right) {
420 return left;
421 }
422
423 if expressions_equal(&left, &right) {
425 if let Expression::Literal(lit) = &left {
426 if let Literal::Number(_) = lit.as_ref() {
427 return Expression::Literal(Box::new(Literal::Number("0".to_string())));
428 }
429 }
430 }
431
432 Expression::Sub(Box::new(BinaryOp::new(left, right)))
433 }
434
435 fn simplify_mul(&mut self, op: BinaryOp) -> Expression {
437 let left = self.simplify_once(op.left);
438 let right = self.simplify_once(op.right);
439
440 if let (Some(a), Some(b)) = (get_number(&left), get_number(&right)) {
442 return Expression::Literal(Box::new(Literal::Number((a * b).to_string())));
443 }
444
445 if is_zero(&right) {
447 return Expression::Literal(Box::new(Literal::Number("0".to_string())));
448 }
449
450 if is_zero(&left) {
452 return Expression::Literal(Box::new(Literal::Number("0".to_string())));
453 }
454
455 if is_one(&right) {
457 return left;
458 }
459
460 if is_one(&left) {
462 return right;
463 }
464
465 Expression::Mul(Box::new(BinaryOp::new(left, right)))
466 }
467
468 fn simplify_div(&mut self, op: BinaryOp) -> Expression {
470 let left = self.simplify_once(op.left);
471 let right = self.simplify_once(op.right);
472
473 if let (Some(a), Some(b)) = (get_number(&left), get_number(&right)) {
475 if b != 0.0 && (a.fract() != 0.0 || b.fract() != 0.0) {
477 return Expression::Literal(Box::new(Literal::Number((a / b).to_string())));
478 }
479 }
480
481 if is_zero(&left) && !is_zero(&right) {
483 return Expression::Literal(Box::new(Literal::Number("0".to_string())));
484 }
485
486 if is_one(&right) {
488 return left;
489 }
490
491 Expression::Div(Box::new(BinaryOp::new(left, right)))
492 }
493
494 fn simplify_neg(&mut self, op: UnaryOp) -> Expression {
496 let inner = self.simplify_once(op.this);
497
498 if let Expression::Neg(inner_neg) = inner {
500 return inner_neg.this;
501 }
502
503 if let Some(n) = get_number(&inner) {
505 return Expression::Literal(Box::new(Literal::Number((-n).to_string())));
506 }
507
508 Expression::Neg(Box::new(UnaryOp {
509 this: inner,
510 inferred_type: None,
511 }))
512 }
513
514 fn simplify_comparison(&mut self, op: BinaryOp, operator: &str) -> Expression {
516 let left = self.simplify_once(op.left);
517 let right = self.simplify_once(op.right);
518
519 if let (Some(a), Some(b)) = (get_number(&left), get_number(&right)) {
521 if let Some(result) = eval_boolean_nums(operator, a, b) {
522 return result;
523 }
524 }
525
526 if let (Some(a), Some(b)) = (get_string(&left), get_string(&right)) {
528 if let Some(result) = eval_boolean_strings(operator, &a, &b) {
529 return result;
530 }
531 }
532
533 if operator == "=" {
535 if let Some(simplified) = self.simplify_equality(left.clone(), right.clone()) {
536 return simplified;
537 }
538 }
539
540 let new_op = BinaryOp::new(left, right);
542
543 match operator {
544 "=" => Expression::Eq(Box::new(new_op)),
545 "!=" | "<>" => Expression::Neq(Box::new(new_op)),
546 ">" => Expression::Gt(Box::new(new_op)),
547 ">=" => Expression::Gte(Box::new(new_op)),
548 "<" => Expression::Lt(Box::new(new_op)),
549 "<=" => Expression::Lte(Box::new(new_op)),
550 _ => Expression::Eq(Box::new(new_op)),
551 }
552 }
553
554 fn simplify_case(&mut self, case: Case) -> Expression {
556 let mut new_whens = Vec::new();
557
558 for (cond, then_expr) in case.whens {
559 let simplified_cond = self.simplify_once(cond);
560
561 if always_true(&simplified_cond) {
563 return self.simplify_once(then_expr);
564 }
565
566 if always_false(&simplified_cond) {
568 continue;
569 }
570
571 new_whens.push((simplified_cond, self.simplify_once(then_expr)));
572 }
573
574 if new_whens.is_empty() {
576 return case
577 .else_
578 .map(|e| self.simplify_once(e))
579 .unwrap_or_else(null);
580 }
581
582 Expression::Case(Box::new(Case {
583 operand: case.operand.map(|e| self.simplify_once(e)),
584 whens: new_whens,
585 else_: case.else_.map(|e| self.simplify_once(e)),
586 comments: Vec::new(),
587 inferred_type: None,
588 }))
589 }
590
591 fn simplify_concat(&mut self, op: BinaryOp) -> Expression {
599 let left = self.simplify_once(op.left);
600 let right = self.simplify_once(op.right);
601
602 if let (Some(a), Some(b)) = (get_string(&left), get_string(&right)) {
604 return Expression::Literal(Box::new(Literal::String(format!("{}{}", a, b))));
605 }
606
607 if let Some(s) = get_string(&left) {
609 if s.is_empty() {
610 return right;
611 }
612 }
613
614 if let Some(s) = get_string(&right) {
616 if s.is_empty() {
617 return left;
618 }
619 }
620
621 if is_null(&left) || is_null(&right) {
623 return null();
624 }
625
626 Expression::Concat(Box::new(BinaryOp::new(left, right)))
627 }
628
629 fn simplify_concat_ws(&mut self, concat_ws: ConcatWs) -> Expression {
636 let separator = self.simplify_once(concat_ws.separator);
637
638 if is_null(&separator) {
640 return null();
641 }
642
643 let expressions: Vec<Expression> = concat_ws
644 .expressions
645 .into_iter()
646 .map(|e| self.simplify_once(e))
647 .filter(|e| !is_null(e)) .collect();
649
650 if expressions.is_empty() {
652 return Expression::Literal(Box::new(Literal::String(String::new())));
653 }
654
655 if let Some(sep) = get_string(&separator) {
657 let all_strings: Option<Vec<String>> =
658 expressions.iter().map(|e| get_string(e)).collect();
659
660 if let Some(strings) = all_strings {
661 return Expression::Literal(Box::new(Literal::String(strings.join(&sep))));
662 }
663 }
664
665 Expression::ConcatWs(Box::new(ConcatWs {
667 separator,
668 expressions,
669 }))
670 }
671
672 fn simplify_paren(&mut self, paren: Paren) -> Expression {
678 let inner = self.simplify_once(paren.this);
679
680 match &inner {
683 Expression::Literal(_)
684 | Expression::Boolean(_)
685 | Expression::Null(_)
686 | Expression::Column(_)
687 | Expression::Paren(_) => inner,
688 _ => Expression::Paren(Box::new(Paren {
690 this: inner,
691 trailing_comments: paren.trailing_comments,
692 })),
693 }
694 }
695
696 fn simplify_datetrunc(&mut self, dt: DateTruncFunc) -> Expression {
701 let inner = self.simplify_once(dt.this);
702
703 Expression::DateTrunc(Box::new(DateTruncFunc {
706 this: inner,
707 unit: dt.unit,
708 }))
709 }
710
711 fn simplify_equality(&mut self, left: Expression, right: Expression) -> Option<Expression> {
718 let right_val = get_number(&right)?;
720
721 match left {
723 Expression::Add(ref op) => {
724 if let Some(c) = get_number(&op.right) {
726 let new_right =
727 Expression::Literal(Box::new(Literal::Number((right_val - c).to_string())));
728 return Some(Expression::Eq(Box::new(BinaryOp::new(
729 op.left.clone(),
730 new_right,
731 ))));
732 }
733 if let Some(c) = get_number(&op.left) {
735 let new_right =
736 Expression::Literal(Box::new(Literal::Number((right_val - c).to_string())));
737 return Some(Expression::Eq(Box::new(BinaryOp::new(
738 op.right.clone(),
739 new_right,
740 ))));
741 }
742 }
743 Expression::Sub(ref op) => {
744 if let Some(c) = get_number(&op.right) {
746 let new_right =
747 Expression::Literal(Box::new(Literal::Number((right_val + c).to_string())));
748 return Some(Expression::Eq(Box::new(BinaryOp::new(
749 op.left.clone(),
750 new_right,
751 ))));
752 }
753 if let Some(c) = get_number(&op.left) {
755 let new_right =
756 Expression::Literal(Box::new(Literal::Number((c - right_val).to_string())));
757 return Some(Expression::Eq(Box::new(BinaryOp::new(
758 op.right.clone(),
759 new_right,
760 ))));
761 }
762 }
763 Expression::Mul(ref op) => {
764 if let Some(c) = get_number(&op.right) {
766 if c != 0.0 && right_val % c == 0.0 {
767 let new_right = Expression::Literal(Box::new(Literal::Number(
768 (right_val / c).to_string(),
769 )));
770 return Some(Expression::Eq(Box::new(BinaryOp::new(
771 op.left.clone(),
772 new_right,
773 ))));
774 }
775 }
776 if let Some(c) = get_number(&op.left) {
778 if c != 0.0 && right_val % c == 0.0 {
779 let new_right = Expression::Literal(Box::new(Literal::Number(
780 (right_val / c).to_string(),
781 )));
782 return Some(Expression::Eq(Box::new(BinaryOp::new(
783 op.right.clone(),
784 new_right,
785 ))));
786 }
787 }
788 }
789 _ => {}
790 }
791
792 None
793 }
794
795 fn simplify_children(&mut self, expr: Expression) -> Expression {
797 match expr {
800 Expression::Alias(mut alias) => {
801 alias.this = self.simplify_once(alias.this);
802 Expression::Alias(alias)
803 }
804 Expression::Between(mut between) => {
805 between.this = self.simplify_once(between.this);
806 between.low = self.simplify_once(between.low);
807 between.high = self.simplify_once(between.high);
808 Expression::Between(between)
809 }
810 Expression::In(mut in_expr) => {
811 in_expr.this = self.simplify_once(in_expr.this);
812 in_expr.expressions = in_expr
813 .expressions
814 .into_iter()
815 .map(|e| self.simplify_once(e))
816 .collect();
817 Expression::In(in_expr)
818 }
819 Expression::Function(mut func) => {
820 func.args = func
821 .args
822 .into_iter()
823 .map(|e| self.simplify_once(e))
824 .collect();
825 Expression::Function(func)
826 }
827 other => other,
829 }
830 }
831}
832
833fn is_one(expr: &Expression) -> bool {
835 match expr {
836 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
837 let Literal::Number(n) = lit.as_ref() else {
838 unreachable!()
839 };
840 if let Ok(num) = n.parse::<f64>() {
841 num == 1.0
842 } else {
843 false
844 }
845 }
846 _ => false,
847 }
848}
849
850fn get_number(expr: &Expression) -> Option<f64> {
852 match expr {
853 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
854 let Literal::Number(n) = lit.as_ref() else {
855 unreachable!()
856 };
857 n.parse().ok()
858 }
859 _ => None,
860 }
861}
862
863fn get_string(expr: &Expression) -> Option<String> {
865 match expr {
866 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
867 let Literal::String(s) = lit.as_ref() else {
868 unreachable!()
869 };
870 Some(s.clone())
871 }
872 _ => None,
873 }
874}
875
876fn expressions_equal(a: &Expression, b: &Expression) -> bool {
878 a == b
879}
880
881fn flatten_and(expr: &Expression) -> Vec<Expression> {
884 match expr {
885 Expression::And(op) => {
886 let mut result = flatten_and(&op.left);
887 result.extend(flatten_and(&op.right));
888 result
889 }
890 other => vec![other.clone()],
891 }
892}
893
894fn flatten_or(expr: &Expression) -> Vec<Expression> {
897 match expr {
898 Expression::Or(op) => {
899 let mut result = flatten_or(&op.left);
900 result.extend(flatten_or(&op.right));
901 result
902 }
903 other => vec![other.clone()],
904 }
905}
906
907fn rebuild_and(operands: Vec<Expression>) -> Expression {
909 if operands.is_empty() {
910 return bool_true(); }
912 let mut result = operands.into_iter();
913 let first = result.next().unwrap();
914 result.fold(first, |acc, op| {
915 Expression::And(Box::new(BinaryOp::new(acc, op)))
916 })
917}
918
919fn rebuild_or(operands: Vec<Expression>) -> Expression {
921 if operands.is_empty() {
922 return bool_false(); }
924 let mut result = operands.into_iter();
925 let first = result.next().unwrap();
926 result.fold(first, |acc, op| {
927 Expression::Or(Box::new(BinaryOp::new(acc, op)))
928 })
929}
930
931fn get_not_inner(expr: &Expression) -> Option<&Expression> {
933 match expr {
934 Expression::Not(op) => Some(&op.this),
935 _ => None,
936 }
937}
938
939pub fn absorb_and_eliminate_and(left: Expression, right: Expression) -> Expression {
948 let left_ops = flatten_and(&left);
950 let right_ops = flatten_and(&right);
951 let all_ops: Vec<Expression> = left_ops.iter().chain(right_ops.iter()).cloned().collect();
952
953 let op_strings: std::collections::HashSet<String> = all_ops.iter().map(gen).collect();
955
956 let mut result_ops: Vec<Expression> = Vec::new();
957 let mut absorbed = std::collections::HashSet::new();
958
959 for (i, op) in all_ops.iter().enumerate() {
960 let op_str = gen(op);
961
962 if absorbed.contains(&op_str) {
964 continue;
965 }
966
967 if let Expression::Or(_) = op {
969 let or_operands = flatten_or(op);
970
971 let absorbed_by_existing = or_operands.iter().any(|or_op| {
974 let or_op_str = gen(or_op);
975 all_ops
977 .iter()
978 .enumerate()
979 .any(|(j, other)| i != j && gen(other) == or_op_str)
980 });
981
982 if absorbed_by_existing {
983 absorbed.insert(op_str);
985 continue;
986 }
987
988 let mut remaining_or_ops: Vec<Expression> = Vec::new();
991 let mut had_complement_absorption = false;
992
993 for or_op in or_operands {
994 let complement_str = if let Some(inner) = get_not_inner(&or_op) {
995 gen(inner)
997 } else {
998 format!("NOT {}", gen(&or_op))
1000 };
1001
1002 let has_complement = all_ops
1004 .iter()
1005 .enumerate()
1006 .any(|(j, other)| i != j && gen(other) == complement_str)
1007 || op_strings.contains(&complement_str);
1008
1009 if has_complement {
1010 had_complement_absorption = true;
1014 } else {
1016 remaining_or_ops.push(or_op);
1017 }
1018 }
1019
1020 if had_complement_absorption {
1021 if remaining_or_ops.is_empty() {
1022 absorbed.insert(op_str);
1025 continue;
1026 } else if remaining_or_ops.len() == 1 {
1027 result_ops.push(remaining_or_ops.into_iter().next().unwrap());
1029 absorbed.insert(op_str);
1030 continue;
1031 } else {
1032 result_ops.push(rebuild_or(remaining_or_ops));
1034 absorbed.insert(op_str);
1035 continue;
1036 }
1037 }
1038 }
1039
1040 result_ops.push(op.clone());
1041 }
1042
1043 let mut seen = std::collections::HashSet::new();
1045 result_ops.retain(|op| seen.insert(gen(op)));
1046
1047 if result_ops.is_empty() {
1048 bool_true()
1049 } else {
1050 rebuild_and(result_ops)
1051 }
1052}
1053
1054pub fn absorb_and_eliminate_or(left: Expression, right: Expression) -> Expression {
1063 let left_ops = flatten_or(&left);
1065 let right_ops = flatten_or(&right);
1066 let all_ops: Vec<Expression> = left_ops.iter().chain(right_ops.iter()).cloned().collect();
1067
1068 let op_strings: std::collections::HashSet<String> = all_ops.iter().map(gen).collect();
1070
1071 let mut result_ops: Vec<Expression> = Vec::new();
1072 let mut absorbed = std::collections::HashSet::new();
1073
1074 for (i, op) in all_ops.iter().enumerate() {
1075 let op_str = gen(op);
1076
1077 if absorbed.contains(&op_str) {
1079 continue;
1080 }
1081
1082 if let Expression::And(_) = op {
1084 let and_operands = flatten_and(op);
1085
1086 let absorbed_by_existing = and_operands.iter().any(|and_op| {
1089 let and_op_str = gen(and_op);
1090 all_ops
1092 .iter()
1093 .enumerate()
1094 .any(|(j, other)| i != j && gen(other) == and_op_str)
1095 });
1096
1097 if absorbed_by_existing {
1098 absorbed.insert(op_str);
1100 continue;
1101 }
1102
1103 let mut remaining_and_ops: Vec<Expression> = Vec::new();
1106 let mut had_complement_absorption = false;
1107
1108 for and_op in and_operands {
1109 let complement_str = if let Some(inner) = get_not_inner(&and_op) {
1110 gen(inner)
1112 } else {
1113 format!("NOT {}", gen(&and_op))
1115 };
1116
1117 let has_complement = all_ops
1119 .iter()
1120 .enumerate()
1121 .any(|(j, other)| i != j && gen(other) == complement_str)
1122 || op_strings.contains(&complement_str);
1123
1124 if has_complement {
1125 had_complement_absorption = true;
1128 } else {
1130 remaining_and_ops.push(and_op);
1131 }
1132 }
1133
1134 if had_complement_absorption {
1135 if remaining_and_ops.is_empty() {
1136 absorbed.insert(op_str);
1139 continue;
1140 } else if remaining_and_ops.len() == 1 {
1141 result_ops.push(remaining_and_ops.into_iter().next().unwrap());
1143 absorbed.insert(op_str);
1144 continue;
1145 } else {
1146 result_ops.push(rebuild_and(remaining_and_ops));
1148 absorbed.insert(op_str);
1149 continue;
1150 }
1151 }
1152 }
1153
1154 result_ops.push(op.clone());
1155 }
1156
1157 let mut seen = std::collections::HashSet::new();
1159 result_ops.retain(|op| seen.insert(gen(op)));
1160
1161 if result_ops.is_empty() {
1162 bool_false()
1163 } else {
1164 rebuild_or(result_ops)
1165 }
1166}
1167
1168pub fn gen(expr: &Expression) -> String {
1170 match expr {
1171 Expression::Literal(lit) => match lit.as_ref() {
1172 Literal::String(s) => format!("'{}'", s),
1173 Literal::Number(n) => n.clone(),
1174 _ => format!("{:?}", lit),
1175 },
1176 Expression::Boolean(b) => if b.value { "TRUE" } else { "FALSE" }.to_string(),
1177 Expression::Null(_) => "NULL".to_string(),
1178 Expression::Column(col) => {
1179 if let Some(ref table) = col.table {
1180 format!("{}.{}", table.name, col.name.name)
1181 } else {
1182 col.name.name.clone()
1183 }
1184 }
1185 Expression::And(op) => format!("({} AND {})", gen(&op.left), gen(&op.right)),
1186 Expression::Or(op) => format!("({} OR {})", gen(&op.left), gen(&op.right)),
1187 Expression::Not(op) => format!("NOT {}", gen(&op.this)),
1188 Expression::Eq(op) => format!("{} = {}", gen(&op.left), gen(&op.right)),
1189 Expression::Neq(op) => format!("{} <> {}", gen(&op.left), gen(&op.right)),
1190 Expression::Gt(op) => format!("{} > {}", gen(&op.left), gen(&op.right)),
1191 Expression::Gte(op) => format!("{} >= {}", gen(&op.left), gen(&op.right)),
1192 Expression::Lt(op) => format!("{} < {}", gen(&op.left), gen(&op.right)),
1193 Expression::Lte(op) => format!("{} <= {}", gen(&op.left), gen(&op.right)),
1194 Expression::Add(op) => format!("{} + {}", gen(&op.left), gen(&op.right)),
1195 Expression::Sub(op) => format!("{} - {}", gen(&op.left), gen(&op.right)),
1196 Expression::Mul(op) => format!("{} * {}", gen(&op.left), gen(&op.right)),
1197 Expression::Div(op) => format!("{} / {}", gen(&op.left), gen(&op.right)),
1198 Expression::Function(f) => {
1199 let args: Vec<String> = f.args.iter().map(|a| gen(a)).collect();
1200 format!("{}({})", f.name.to_uppercase(), args.join(", "))
1201 }
1202 _ => super::structural_identity_key(expr),
1203 }
1204}
1205
1206#[cfg(test)]
1207mod tests {
1208 use super::*;
1209
1210 #[test]
1211 fn test_source_spans_do_not_change_simplification_or_identity_keys() {
1212 let left = crate::Parser::parse_sql("CAST(x AS BOOLEAN)")
1213 .unwrap()
1214 .remove(0);
1215 let right = crate::Parser::parse_sql(" CAST(x AS BOOLEAN)")
1216 .unwrap()
1217 .remove(0);
1218 assert_eq!(left, right);
1219 assert_eq!(gen(&left), gen(&right));
1220 assert!(is_complement(
1221 &left,
1222 &Expression::Not(Box::new(UnaryOp::new(right.clone())))
1223 ));
1224 let result = simplify(
1225 Expression::And(Box::new(BinaryOp::new(left.clone(), right))),
1226 None,
1227 );
1228 assert_eq!(result, left);
1229 }
1230
1231 fn make_int(val: i64) -> Expression {
1232 Expression::Literal(Box::new(Literal::Number(val.to_string())))
1233 }
1234
1235 fn make_string(val: &str) -> Expression {
1236 Expression::Literal(Box::new(Literal::String(val.to_string())))
1237 }
1238
1239 fn make_bool(val: bool) -> Expression {
1240 Expression::Boolean(BooleanLiteral { value: val })
1241 }
1242
1243 fn make_column(name: &str) -> Expression {
1244 use crate::expressions::{Column, Identifier};
1245 Expression::boxed_column(Column {
1246 name: Identifier::new(name),
1247 table: None,
1248 join_mark: false,
1249 trailing_comments: vec![],
1250 span: None,
1251 inferred_type: None,
1252 })
1253 }
1254
1255 #[test]
1256 fn test_always_true_false() {
1257 assert!(always_true(&make_bool(true)));
1258 assert!(!always_true(&make_bool(false)));
1259 assert!(always_true(&make_int(1)));
1260 assert!(!always_true(&make_int(0)));
1261
1262 assert!(always_false(&make_bool(false)));
1263 assert!(!always_false(&make_bool(true)));
1264 assert!(always_false(&null()));
1265 assert!(always_false(&make_int(0)));
1266 }
1267
1268 #[test]
1269 fn test_simplify_and_with_true() {
1270 let mut simplifier = Simplifier::new(None);
1271
1272 let expr = Expression::And(Box::new(BinaryOp::new(make_bool(true), make_bool(true))));
1274 let result = simplifier.simplify(expr);
1275 assert!(always_true(&result));
1276
1277 let expr = Expression::And(Box::new(BinaryOp::new(make_bool(true), make_bool(false))));
1279 let result = simplifier.simplify(expr);
1280 assert!(always_false(&result));
1281
1282 let x = make_int(42);
1284 let expr = Expression::And(Box::new(BinaryOp::new(make_bool(true), x.clone())));
1285 let result = simplifier.simplify(expr);
1286 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1287 }
1288
1289 #[test]
1290 fn test_simplify_or_with_false() {
1291 let mut simplifier = Simplifier::new(None);
1292
1293 let expr = Expression::Or(Box::new(BinaryOp::new(make_bool(false), make_bool(false))));
1295 let result = simplifier.simplify(expr);
1296 assert!(always_false(&result));
1297
1298 let expr = Expression::Or(Box::new(BinaryOp::new(make_bool(false), make_bool(true))));
1300 let result = simplifier.simplify(expr);
1301 assert!(always_true(&result));
1302
1303 let x = make_int(42);
1305 let expr = Expression::Or(Box::new(BinaryOp::new(make_bool(false), x.clone())));
1306 let result = simplifier.simplify(expr);
1307 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1308 }
1309
1310 #[test]
1311 fn test_simplify_not() {
1312 let mut simplifier = Simplifier::new(None);
1313
1314 let expr = Expression::Not(Box::new(UnaryOp::new(make_bool(true))));
1316 let result = simplifier.simplify(expr);
1317 assert!(is_false(&result));
1318
1319 let expr = Expression::Not(Box::new(UnaryOp::new(make_bool(false))));
1321 let result = simplifier.simplify(expr);
1322 assert!(always_true(&result));
1323
1324 let x = make_int(42);
1326 let inner_not = Expression::Not(Box::new(UnaryOp::new(x.clone())));
1327 let expr = Expression::Not(Box::new(UnaryOp::new(inner_not)));
1328 let result = simplifier.simplify(expr);
1329 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1330 }
1331
1332 #[test]
1333 fn test_simplify_demorgan_comparison() {
1334 let mut simplifier = Simplifier::new(None);
1335
1336 let a = make_column("a");
1338 let b = make_column("b");
1339 let eq = Expression::Eq(Box::new(BinaryOp::new(a.clone(), b.clone())));
1340 let expr = Expression::Not(Box::new(UnaryOp::new(eq)));
1341 let result = simplifier.simplify(expr);
1342 assert!(matches!(result, Expression::Neq(_)));
1343
1344 let gt = Expression::Gt(Box::new(BinaryOp::new(a, b)));
1346 let expr = Expression::Not(Box::new(UnaryOp::new(gt)));
1347 let result = simplifier.simplify(expr);
1348 assert!(matches!(result, Expression::Lte(_)));
1349 }
1350
1351 #[test]
1352 fn test_constant_folding_add() {
1353 let mut simplifier = Simplifier::new(None);
1354
1355 let expr = Expression::Add(Box::new(BinaryOp::new(make_int(1), make_int(2))));
1357 let result = simplifier.simplify(expr);
1358 assert_eq!(get_number(&result), Some(3.0));
1359
1360 let x = make_int(42);
1362 let expr = Expression::Add(Box::new(BinaryOp::new(x.clone(), make_int(0))));
1363 let result = simplifier.simplify(expr);
1364 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1365 }
1366
1367 #[test]
1368 fn test_constant_folding_mul() {
1369 let mut simplifier = Simplifier::new(None);
1370
1371 let expr = Expression::Mul(Box::new(BinaryOp::new(make_int(3), make_int(4))));
1373 let result = simplifier.simplify(expr);
1374 assert_eq!(get_number(&result), Some(12.0));
1375
1376 let x = make_int(42);
1378 let expr = Expression::Mul(Box::new(BinaryOp::new(x, make_int(0))));
1379 let result = simplifier.simplify(expr);
1380 assert_eq!(get_number(&result), Some(0.0));
1381
1382 let x = make_int(42);
1384 let expr = Expression::Mul(Box::new(BinaryOp::new(x.clone(), make_int(1))));
1385 let result = simplifier.simplify(expr);
1386 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1387 }
1388
1389 #[test]
1390 fn test_constant_folding_comparison() {
1391 let mut simplifier = Simplifier::new(None);
1392
1393 let expr = Expression::Eq(Box::new(BinaryOp::new(make_int(1), make_int(1))));
1395 let result = simplifier.simplify(expr);
1396 assert!(always_true(&result));
1397
1398 let expr = Expression::Eq(Box::new(BinaryOp::new(make_int(1), make_int(2))));
1400 let result = simplifier.simplify(expr);
1401 assert!(is_false(&result));
1402
1403 let expr = Expression::Gt(Box::new(BinaryOp::new(make_int(3), make_int(2))));
1405 let result = simplifier.simplify(expr);
1406 assert!(always_true(&result));
1407
1408 let expr = Expression::Eq(Box::new(BinaryOp::new(
1410 make_string("abc"),
1411 make_string("abc"),
1412 )));
1413 let result = simplifier.simplify(expr);
1414 assert!(always_true(&result));
1415 }
1416
1417 #[test]
1418 fn test_simplify_negation() {
1419 let mut simplifier = Simplifier::new(None);
1420
1421 let inner = Expression::Neg(Box::new(UnaryOp::new(make_int(5))));
1423 let expr = Expression::Neg(Box::new(UnaryOp::new(inner)));
1424 let result = simplifier.simplify(expr);
1425 assert_eq!(get_number(&result), Some(5.0));
1426
1427 let expr = Expression::Neg(Box::new(UnaryOp::new(make_int(3))));
1429 let result = simplifier.simplify(expr);
1430 assert_eq!(get_number(&result), Some(-3.0));
1431 }
1432
1433 #[test]
1434 fn test_gen_simple() {
1435 assert_eq!(gen(&make_int(42)), "42");
1436 assert_eq!(gen(&make_string("hello")), "'hello'");
1437 assert_eq!(gen(&make_bool(true)), "TRUE");
1438 assert_eq!(gen(&make_bool(false)), "FALSE");
1439 assert_eq!(gen(&null()), "NULL");
1440 }
1441
1442 #[test]
1443 fn test_gen_operations() {
1444 let add = Expression::Add(Box::new(BinaryOp::new(make_int(1), make_int(2))));
1445 assert_eq!(gen(&add), "1 + 2");
1446
1447 let and = Expression::And(Box::new(BinaryOp::new(make_bool(true), make_bool(false))));
1448 assert_eq!(gen(&and), "(TRUE AND FALSE)");
1449 }
1450
1451 #[test]
1452 fn test_complement_elimination() {
1453 let mut simplifier = Simplifier::new(None);
1454
1455 let x = make_int(42);
1457 let not_x = Expression::Not(Box::new(UnaryOp::new(x.clone())));
1458 let expr = Expression::And(Box::new(BinaryOp::new(x, not_x)));
1459 let result = simplifier.simplify(expr);
1460 assert!(is_false(&result));
1461 }
1462
1463 #[test]
1464 fn test_idempotent() {
1465 let mut simplifier = Simplifier::new(None);
1466
1467 let x = make_int(42);
1469 let expr = Expression::And(Box::new(BinaryOp::new(x.clone(), x.clone())));
1470 let result = simplifier.simplify(expr);
1471 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1472
1473 let x = make_int(42);
1475 let expr = Expression::Or(Box::new(BinaryOp::new(x.clone(), x.clone())));
1476 let result = simplifier.simplify(expr);
1477 assert_eq!(format!("{:?}", result), format!("{:?}", x));
1478 }
1479
1480 #[test]
1481 fn test_absorption_and() {
1482 let mut simplifier = Simplifier::new(None);
1483
1484 let a = make_column("a");
1486 let b = make_column("b");
1487 let a_or_b = Expression::Or(Box::new(BinaryOp::new(a.clone(), b.clone())));
1488 let expr = Expression::And(Box::new(BinaryOp::new(a.clone(), a_or_b)));
1489 let result = simplifier.simplify(expr);
1490 assert_eq!(gen(&result), gen(&a));
1492 }
1493
1494 #[test]
1495 fn test_absorption_or() {
1496 let mut simplifier = Simplifier::new(None);
1497
1498 let a = make_column("a");
1500 let b = make_column("b");
1501 let a_and_b = Expression::And(Box::new(BinaryOp::new(a.clone(), b.clone())));
1502 let expr = Expression::Or(Box::new(BinaryOp::new(a.clone(), a_and_b)));
1503 let result = simplifier.simplify(expr);
1504 assert_eq!(gen(&result), gen(&a));
1506 }
1507
1508 #[test]
1509 fn test_absorption_with_complement_and() {
1510 let mut simplifier = Simplifier::new(None);
1511
1512 let a = make_column("a");
1514 let b = make_column("b");
1515 let not_a = Expression::Not(Box::new(UnaryOp::new(a.clone())));
1516 let not_a_or_b = Expression::Or(Box::new(BinaryOp::new(not_a, b.clone())));
1517 let expr = Expression::And(Box::new(BinaryOp::new(a.clone(), not_a_or_b)));
1518 let result = simplifier.simplify(expr);
1519 let expected = Expression::And(Box::new(BinaryOp::new(a, b)));
1521 assert_eq!(gen(&result), gen(&expected));
1522 }
1523
1524 #[test]
1525 fn test_absorption_with_complement_or() {
1526 let mut simplifier = Simplifier::new(None);
1527
1528 let a = make_column("a");
1530 let b = make_column("b");
1531 let not_a = Expression::Not(Box::new(UnaryOp::new(a.clone())));
1532 let not_a_and_b = Expression::And(Box::new(BinaryOp::new(not_a, b.clone())));
1533 let expr = Expression::Or(Box::new(BinaryOp::new(a.clone(), not_a_and_b)));
1534 let result = simplifier.simplify(expr);
1535 let expected = Expression::Or(Box::new(BinaryOp::new(a, b)));
1537 assert_eq!(gen(&result), gen(&expected));
1538 }
1539
1540 #[test]
1541 fn test_flatten_and() {
1542 let a = make_column("a");
1544 let b = make_column("b");
1545 let c = make_column("c");
1546 let b_and_c = Expression::And(Box::new(BinaryOp::new(b.clone(), c.clone())));
1547 let expr = Expression::And(Box::new(BinaryOp::new(a.clone(), b_and_c)));
1548 let flattened = flatten_and(&expr);
1549 assert_eq!(flattened.len(), 3);
1550 assert_eq!(gen(&flattened[0]), "a");
1551 assert_eq!(gen(&flattened[1]), "b");
1552 assert_eq!(gen(&flattened[2]), "c");
1553 }
1554
1555 #[test]
1556 fn test_flatten_or() {
1557 let a = make_column("a");
1559 let b = make_column("b");
1560 let c = make_column("c");
1561 let b_or_c = Expression::Or(Box::new(BinaryOp::new(b.clone(), c.clone())));
1562 let expr = Expression::Or(Box::new(BinaryOp::new(a.clone(), b_or_c)));
1563 let flattened = flatten_or(&expr);
1564 assert_eq!(flattened.len(), 3);
1565 assert_eq!(gen(&flattened[0]), "a");
1566 assert_eq!(gen(&flattened[1]), "b");
1567 assert_eq!(gen(&flattened[2]), "c");
1568 }
1569
1570 #[test]
1571 fn test_simplify_concat() {
1572 let mut simplifier = Simplifier::new(None);
1573
1574 let expr = Expression::Concat(Box::new(BinaryOp::new(
1576 make_string("hello"),
1577 make_string("world"),
1578 )));
1579 let result = simplifier.simplify(expr);
1580 assert_eq!(get_string(&result), Some("helloworld".to_string()));
1581
1582 let x = make_string("test");
1584 let expr = Expression::Concat(Box::new(BinaryOp::new(make_string(""), x.clone())));
1585 let result = simplifier.simplify(expr);
1586 assert_eq!(get_string(&result), Some("test".to_string()));
1587
1588 let expr = Expression::Concat(Box::new(BinaryOp::new(x, make_string(""))));
1590 let result = simplifier.simplify(expr);
1591 assert_eq!(get_string(&result), Some("test".to_string()));
1592
1593 let expr = Expression::Concat(Box::new(BinaryOp::new(null(), make_string("test"))));
1595 let result = simplifier.simplify(expr);
1596 assert!(is_null(&result));
1597 }
1598
1599 #[test]
1600 fn test_simplify_concat_ws() {
1601 let mut simplifier = Simplifier::new(None);
1602
1603 let expr = Expression::ConcatWs(Box::new(ConcatWs {
1605 separator: make_string(","),
1606 expressions: vec![make_string("a"), make_string("b"), make_string("c")],
1607 }));
1608 let result = simplifier.simplify(expr);
1609 assert_eq!(get_string(&result), Some("a,b,c".to_string()));
1610
1611 let expr = Expression::ConcatWs(Box::new(ConcatWs {
1613 separator: null(),
1614 expressions: vec![make_string("a"), make_string("b")],
1615 }));
1616 let result = simplifier.simplify(expr);
1617 assert!(is_null(&result));
1618
1619 let expr = Expression::ConcatWs(Box::new(ConcatWs {
1621 separator: make_string(","),
1622 expressions: vec![],
1623 }));
1624 let result = simplifier.simplify(expr);
1625 assert_eq!(get_string(&result), Some("".to_string()));
1626
1627 let expr = Expression::ConcatWs(Box::new(ConcatWs {
1629 separator: make_string("-"),
1630 expressions: vec![make_string("a"), null(), make_string("b")],
1631 }));
1632 let result = simplifier.simplify(expr);
1633 assert_eq!(get_string(&result), Some("a-b".to_string()));
1634 }
1635
1636 #[test]
1637 fn test_simplify_paren() {
1638 let mut simplifier = Simplifier::new(None);
1639
1640 let expr = Expression::Paren(Box::new(Paren {
1642 this: make_int(42),
1643 trailing_comments: vec![],
1644 }));
1645 let result = simplifier.simplify(expr);
1646 assert_eq!(get_number(&result), Some(42.0));
1647
1648 let expr = Expression::Paren(Box::new(Paren {
1650 this: make_bool(true),
1651 trailing_comments: vec![],
1652 }));
1653 let result = simplifier.simplify(expr);
1654 assert!(is_boolean_true(&result));
1655
1656 let expr = Expression::Paren(Box::new(Paren {
1658 this: null(),
1659 trailing_comments: vec![],
1660 }));
1661 let result = simplifier.simplify(expr);
1662 assert!(is_null(&result));
1663
1664 let inner_paren = Expression::Paren(Box::new(Paren {
1666 this: make_int(10),
1667 trailing_comments: vec![],
1668 }));
1669 let expr = Expression::Paren(Box::new(Paren {
1670 this: inner_paren,
1671 trailing_comments: vec![],
1672 }));
1673 let result = simplifier.simplify(expr);
1674 assert_eq!(get_number(&result), Some(10.0));
1675 }
1676
1677 #[test]
1678 fn test_simplify_equality_solve() {
1679 let mut simplifier = Simplifier::new(None);
1680
1681 let x = make_column("x");
1683 let x_plus_1 = Expression::Add(Box::new(BinaryOp::new(x.clone(), make_int(1))));
1684 let expr = Expression::Eq(Box::new(BinaryOp::new(x_plus_1, make_int(3))));
1685 let result = simplifier.simplify(expr);
1686 if let Expression::Eq(op) = &result {
1688 assert_eq!(gen(&op.left), "x");
1689 assert_eq!(get_number(&op.right), Some(2.0));
1690 } else {
1691 panic!("Expected Eq expression");
1692 }
1693
1694 let x_minus_1 = Expression::Sub(Box::new(BinaryOp::new(x.clone(), make_int(1))));
1696 let expr = Expression::Eq(Box::new(BinaryOp::new(x_minus_1, make_int(3))));
1697 let result = simplifier.simplify(expr);
1698 if let Expression::Eq(op) = &result {
1699 assert_eq!(gen(&op.left), "x");
1700 assert_eq!(get_number(&op.right), Some(4.0));
1701 } else {
1702 panic!("Expected Eq expression");
1703 }
1704
1705 let x_times_2 = Expression::Mul(Box::new(BinaryOp::new(x.clone(), make_int(2))));
1707 let expr = Expression::Eq(Box::new(BinaryOp::new(x_times_2, make_int(6))));
1708 let result = simplifier.simplify(expr);
1709 if let Expression::Eq(op) = &result {
1710 assert_eq!(gen(&op.left), "x");
1711 assert_eq!(get_number(&op.right), Some(3.0));
1712 } else {
1713 panic!("Expected Eq expression");
1714 }
1715
1716 let one_plus_x = Expression::Add(Box::new(BinaryOp::new(make_int(1), x.clone())));
1718 let expr = Expression::Eq(Box::new(BinaryOp::new(one_plus_x, make_int(3))));
1719 let result = simplifier.simplify(expr);
1720 if let Expression::Eq(op) = &result {
1721 assert_eq!(gen(&op.left), "x");
1722 assert_eq!(get_number(&op.right), Some(2.0));
1723 } else {
1724 panic!("Expected Eq expression");
1725 }
1726 }
1727
1728 #[test]
1729 fn test_simplify_datetrunc() {
1730 use crate::expressions::DateTimeField;
1731 let mut simplifier = Simplifier::new(None);
1732
1733 let x = make_column("x");
1735 let expr = Expression::DateTrunc(Box::new(DateTruncFunc {
1736 this: x.clone(),
1737 unit: DateTimeField::Day,
1738 }));
1739 let result = simplifier.simplify(expr);
1740 if let Expression::DateTrunc(dt) = &result {
1741 assert_eq!(gen(&dt.this), "x");
1742 assert_eq!(dt.unit, DateTimeField::Day);
1743 } else {
1744 panic!("Expected DateTrunc expression");
1745 }
1746 }
1747}