cynos_query/executor/
filter.rs1use crate::ast::Predicate;
4use crate::executor::{Relation, RelationEntry};
5use alloc::vec::Vec;
6
7pub struct FilterExecutor<P: Predicate> {
9 predicate: P,
10}
11
12impl<P: Predicate> FilterExecutor<P> {
13 pub fn new(predicate: P) -> Self {
15 Self { predicate }
16 }
17
18 pub fn execute(&self, input: Relation) -> Relation {
20 let tables = input.tables().to_vec();
21 let table_column_counts = input.table_column_counts().to_vec();
22 let entries: Vec<RelationEntry> = input
23 .into_iter()
24 .filter(|entry| self.predicate.eval(&entry.row))
25 .collect();
26
27 Relation { entries, tables, table_column_counts }
28 }
29}
30
31#[allow(dead_code)]
33pub fn filter_relation<F>(input: Relation, predicate: F) -> Relation
34where
35 F: Fn(&RelationEntry) -> bool,
36{
37 let tables = input.tables().to_vec();
38 let table_column_counts = input.table_column_counts().to_vec();
39 let entries: Vec<RelationEntry> = input.into_iter().filter(|e| predicate(e)).collect();
40
41 Relation { entries, tables, table_column_counts }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::ast::{ColumnRef, EvalType, ValuePredicate};
48 use alloc::vec;
49 use cynos_core::{Row, Value};
50
51 #[test]
52 fn test_filter_executor() {
53 let rows = vec![
54 Row::new(1, vec![Value::Int64(10)]),
55 Row::new(2, vec![Value::Int64(20)]),
56 Row::new(3, vec![Value::Int64(30)]),
57 ];
58 let input = Relation::from_rows_owned(rows, vec!["t".into()]);
59
60 let col = ColumnRef::new("t", "value", 0);
61 let pred = ValuePredicate::new(col, EvalType::Gt, Value::Int64(15));
62 let executor = FilterExecutor::new(pred);
63
64 let result = executor.execute(input);
65 assert_eq!(result.len(), 2);
66 }
67
68 #[test]
69 fn test_filter_relation_closure() {
70 let rows = vec![
71 Row::new(1, vec![Value::Int64(10)]),
72 Row::new(2, vec![Value::Int64(20)]),
73 ];
74 let input = Relation::from_rows_owned(rows, vec!["t".into()]);
75
76 let result = filter_relation(input, |entry| {
77 entry
78 .get_field(0)
79 .and_then(|v| v.as_i64())
80 .map(|v| v > 15)
81 .unwrap_or(false)
82 });
83
84 assert_eq!(result.len(), 1);
85 }
86}