1use crate::compiler::IrCompiledFilter;
6
7pub struct CompiledFilter {
9 ir: IrCompiledFilter,
10}
11
12impl CompiledFilter {
13 pub fn new(
15 expr: crate::expr::FilterExpr,
16 schema: std::sync::Arc<crate::schema::FilterSchema>,
17 functions: std::sync::Arc<crate::functions::FunctionRegistry>,
18 ) -> Self {
19 let ir = crate::compiler::DefaultCompiler::compile(expr, schema, functions);
20 Self { ir }
21 }
22 pub fn execute(
24 &self,
25 context: &crate::context::FilterContext,
26 ) -> Result<bool, crate::WirerustError> {
27 self.ir.execute(context)
28 }
29 pub fn schema(&self) -> &crate::schema::FilterSchema {
31 &self.ir.schema
32 }
33 pub fn functions(&self) -> &crate::functions::FunctionRegistry {
35 &self.ir.functions
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::context::FilterContext;
43 use crate::expr::{ComparisonOp, FilterExpr};
44 use crate::functions::FunctionRegistry;
45 use crate::schema::FilterSchema;
46 use crate::schema::FilterSchemaBuilder;
47 use crate::types::{FieldType, LiteralValue};
48 use std::sync::Arc;
49
50 fn schema() -> FilterSchema {
51 FilterSchemaBuilder::new()
52 .field("foo", FieldType::Int)
53 .field("bar", FieldType::Bytes)
54 .build()
55 }
56
57 fn context() -> FilterContext {
58 let mut ctx = FilterContext::new();
59 let sch = schema();
60 ctx.set("foo", LiteralValue::Int(42), &sch).unwrap();
61 ctx.set("bar", LiteralValue::Bytes(Arc::new(b"baz".to_vec())), &sch)
62 .unwrap();
63 ctx
64 }
65
66 #[test]
67 fn test_compiled_filter_execute_true() {
68 let expr = FilterExpr::Comparison {
69 left: Box::new(FilterExpr::Value(LiteralValue::Bytes(Arc::new(
70 b"foo".to_vec(),
71 )))),
72 op: ComparisonOp::Eq,
73 right: Box::new(FilterExpr::Value(LiteralValue::Int(42))),
74 };
75 let filter =
76 CompiledFilter::new(expr, Arc::new(schema()), Arc::new(FunctionRegistry::new()));
77 assert!(filter.execute(&context()).unwrap());
78 }
79
80 #[test]
81 fn test_compiled_filter_execute_false() {
82 let expr = FilterExpr::Comparison {
83 left: Box::new(FilterExpr::Value(LiteralValue::Bytes(Arc::new(
84 b"foo".to_vec(),
85 )))),
86 op: ComparisonOp::Eq,
87 right: Box::new(FilterExpr::Value(LiteralValue::Int(0))),
88 };
89 let filter =
90 CompiledFilter::new(expr, Arc::new(schema()), Arc::new(FunctionRegistry::new()));
91 assert!(!filter.execute(&context()).unwrap());
92 }
93
94 #[test]
95 fn test_compiled_filter_schema_access() {
96 let expr = FilterExpr::Comparison {
97 left: Box::new(FilterExpr::Value(LiteralValue::Bytes(Arc::new(
98 b"foo".to_vec(),
99 )))),
100 op: ComparisonOp::Eq,
101 right: Box::new(FilterExpr::Value(LiteralValue::Int(42))),
102 };
103 let filter =
104 CompiledFilter::new(expr, Arc::new(schema()), Arc::new(FunctionRegistry::new()));
105 let sch = filter.schema();
106 assert_eq!(sch.get_field_type("foo"), Some(&FieldType::Int));
107 }
108}