uni_query_functions/rewrite/rules/
btic.rs1use crate::rewrite::context::RewriteContext;
6use crate::rewrite::error::RewriteError;
7use crate::rewrite::rule::{Arity, RewriteRule};
8use uni_cypher::ast::{BinaryOp, Expr};
9
10pub struct BticContainsPointRule;
19
20impl RewriteRule for BticContainsPointRule {
21 fn function_name(&self) -> &str {
22 "btic_contains_point"
23 }
24
25 fn validate_args(&self, args: &[Expr]) -> Result<(), RewriteError> {
26 Arity::Exact(2).check(args.len())
27 }
28
29 fn rewrite(&self, args: Vec<Expr>, _ctx: &RewriteContext) -> Result<Expr, RewriteError> {
30 let btic_expr = args[0].clone();
31 let point = args[1].clone();
32
33 let lo_check = Expr::BinaryOp {
35 left: Box::new(Expr::FunctionCall {
36 name: "btic_lo".to_string(),
37 args: vec![btic_expr.clone()],
38 distinct: false,
39 window_spec: None,
40 }),
41 op: BinaryOp::LtEq,
42 right: Box::new(point.clone()),
43 };
44
45 let hi_check = Expr::BinaryOp {
47 left: Box::new(Expr::FunctionCall {
48 name: "btic_hi".to_string(),
49 args: vec![btic_expr],
50 distinct: false,
51 window_spec: None,
52 }),
53 op: BinaryOp::Gt,
54 right: Box::new(point),
55 };
56
57 Ok(Expr::BinaryOp {
59 left: Box::new(lo_check),
60 op: BinaryOp::And,
61 right: Box::new(hi_check),
62 })
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::rewrite::context::RewriteContext;
70 use uni_cypher::ast::CypherLiteral;
71
72 #[test]
73 fn test_btic_contains_point_rewrite() {
74 let rule = BticContainsPointRule;
75 let ctx = RewriteContext::default();
76
77 let args = vec![
78 Expr::Property(Box::new(Expr::Variable("n".into())), "valid_at".into()),
79 Expr::Literal(CypherLiteral::Integer(489_024_000_000)),
80 ];
81
82 assert!(rule.validate_args(&args).is_ok());
83
84 let result = rule.rewrite(args, &ctx).unwrap();
85
86 match result {
88 Expr::BinaryOp {
89 op: BinaryOp::And, ..
90 } => {} other => panic!("expected AND expression, got: {other:?}"),
92 }
93 }
94
95 #[test]
96 fn test_btic_contains_point_wrong_arity() {
97 let rule = BticContainsPointRule;
98 let args = vec![Expr::Variable("x".into())];
99 assert!(rule.validate_args(&args).is_err());
100 }
101}