use super::test_schema;
use crate::engine::simplify::Simplify;
use toasty_core::stmt::{self, Expr, ExprMatch, MatchArm, Projection, Value, VisitMut};
#[test]
fn constant_subject_folds_to_arm_value() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::from(2i64)),
arms: vec![
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("a"),
},
MatchArm {
pattern: Value::from(2i64),
expr: Expr::from("b"),
},
MatchArm {
pattern: Value::from(3i64),
expr: Expr::from("c"),
},
],
else_expr: Box::new(Expr::null()),
});
simplify.visit_expr_mut(&mut expr);
assert!(matches!(&expr, Expr::Value(Value::String(s)) if s == "b"));
}
#[test]
fn subject_simplified_before_folding() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let subject = stmt::ExprProject {
base: Box::new(Expr::record([Expr::from(1i64)])),
projection: Projection::from(0),
};
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::Project(subject)),
arms: vec![
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("matched"),
},
MatchArm {
pattern: Value::from(2i64),
expr: Expr::from("other"),
},
],
else_expr: Box::new(Expr::null()),
});
simplify.visit_expr_mut(&mut expr);
assert!(matches!(&expr, Expr::Value(Value::String(s)) if s == "matched"));
}
#[test]
fn dead_arms_not_visited_with_constant_subject() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let dead_arm_expr = stmt::ExprProject {
base: Box::new(Expr::record([Expr::from(1i64)])),
projection: Projection::from(1), };
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::from(1i64)),
arms: vec![
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("ok"),
},
MatchArm {
pattern: Value::from(2i64),
expr: Expr::Project(dead_arm_expr),
},
],
else_expr: Box::new(Expr::null()),
});
simplify.visit_expr_mut(&mut expr);
assert!(matches!(&expr, Expr::Value(Value::String(s)) if s == "ok"));
}
#[test]
fn non_constant_subject_simplifies_all_arms() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![
MatchArm {
pattern: Value::from(1i64),
expr: Expr::record([Expr::from("hello")]),
},
MatchArm {
pattern: Value::from(2i64),
expr: Expr::record([Expr::from("world")]),
},
],
else_expr: Box::new(Expr::null()),
});
simplify.visit_expr_mut(&mut expr);
let Expr::Match(m) = &expr else {
panic!("expected Expr::Match")
};
assert!(matches!(&m.arms[0].expr, Expr::Value(Value::Record(_))));
assert!(matches!(&m.arms[1].expr, Expr::Value(Value::Record(_))));
}
#[test]
fn constant_subject_no_match_folds_to_error_else() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::from(99i64)),
arms: vec![MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("a"),
}],
else_expr: Box::new(Expr::error("unexpected")),
});
simplify.visit_expr_mut(&mut expr);
assert!(matches!(&expr, Expr::Error(e) if e.message == "unexpected"));
}
#[test]
fn constant_subject_matching_arm_is_error() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::from(1i64)),
arms: vec![
MatchArm {
pattern: Value::from(1i64),
expr: Expr::error("bad"),
},
MatchArm {
pattern: Value::from(2i64),
expr: Expr::from("ok"),
},
],
else_expr: Box::new(Expr::from("default")),
});
simplify.visit_expr_mut(&mut expr);
assert!(matches!(&expr, Expr::Error(e) if e.message == "bad"));
}
#[test]
fn constant_subject_match_found_error_else_not_reached() {
let schema = test_schema();
let mut simplify = Simplify::new(&schema, &toasty_core::driver::Capability::SQLITE);
let mut expr = Expr::Match(ExprMatch {
subject: Box::new(Expr::from(1i64)),
arms: vec![MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("ok"),
}],
else_expr: Box::new(Expr::error("unexpected")),
});
simplify.visit_expr_mut(&mut expr);
assert!(matches!(&expr, Expr::Value(Value::String(s)) if s == "ok"));
}