1pub mod execution;
4
5use crate::execution::physical_plan::PhysicalPlan;
6use crate::execution::metrics::ExecutionMetrics;
7use kotoba_core::types::Value;
9use kotoba_errors::KotobaError;
10
11type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
13
14#[async_trait::async_trait]
15pub trait QueryExecutor: Send + Sync {
16 async fn execute(&self, plan: PhysicalPlan) -> Result<Vec<Value>>;
17}
18
19pub struct DefaultQueryExecutor {
20 }
22
23impl DefaultQueryExecutor {
24 pub fn new() -> Self {
25 Self { }
26 }
27}
28
29#[async_trait::async_trait]
30impl QueryExecutor for DefaultQueryExecutor {
31 async fn execute(&self, plan: PhysicalPlan) -> Result<Vec<Value>> {
32 let mut metrics = ExecutionMetrics::new();
33 Ok(vec![])
35 }
36}
37
38pub mod planner;
39pub mod prelude {
40 pub use crate::execution::*;
42 pub use crate::planner::*;
43 }
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use crate::prelude::*;
51 use kotoba_core::{types::*, ir::*};
52 use std::collections::HashMap;
53
54 #[test]
55 fn test_query_executor_creation() {
56 let executor = QueryExecutor::new();
57 assert!(true);
59 }
60
61 #[test]
62 fn test_gql_parser_creation() {
63 let parser = GqlParser::new();
64 assert!(true);
66 }
67
68 #[test]
69 fn test_gql_parser_tokenize() {
70 let mut parser = GqlParser::new();
71 let result = parser.parse("MATCH (n:Person) RETURN n");
72 assert!(result.is_ok() || result.is_err()); }
76
77 #[test]
78 fn test_expression_evaluation() {
79 use execution::executor::QueryExecutor;
80 let executor = QueryExecutor::new();
81
82 let mut row_data = HashMap::new();
84 row_data.insert("name".to_string(), Value::String("Alice".to_string()));
85 row_data.insert("age".to_string(), Value::Int(30));
86 let row = Row { values: row_data };
87
88 let expr = Expr::Var("name".to_string());
90 let result = executor.evaluate_expr(&row, &expr);
91 assert!(result.is_ok());
92 assert_eq!(result.unwrap(), Value::String("Alice".to_string()));
93
94 let expr = Expr::Const(Value::Int(42));
96 let result = executor.evaluate_expr(&row, &expr);
97 assert!(result.is_ok());
98 assert_eq!(result.unwrap(), Value::Int(42));
99 }
100
101 #[test]
102 fn test_math_functions() {
103 use execution::executor::QueryExecutor;
104 let executor = QueryExecutor::new();
105
106 let row = Row { values: HashMap::new() };
107
108 let expr = Expr::Fn {
110 fn_: "abs".to_string(),
111 args: vec![Expr::Const(Value::Int(-5))],
112 };
113 let result = executor.evaluate_expr(&row, &expr);
114 assert!(result.is_ok());
115 assert_eq!(result.unwrap(), Value::Int(5));
116
117 let expr = Expr::Fn {
119 fn_: "sqrt".to_string(),
120 args: vec![Expr::Const(Value::Int(9))],
121 };
122 let result = executor.evaluate_expr(&row, &expr);
123 assert!(result.is_ok());
124 assert_eq!(result.unwrap(), Value::Int(3));
125 }
126
127 #[test]
128 fn test_string_functions() {
129 use execution::executor::QueryExecutor;
130 let executor = QueryExecutor::new();
131
132 let row = Row { values: HashMap::new() };
133
134 let expr = Expr::Fn {
136 fn_: "length".to_string(),
137 args: vec![Expr::Const(Value::String("hello".to_string()))],
138 };
139 let result = executor.evaluate_expr(&row, &expr);
140 assert!(result.is_ok());
141 assert_eq!(result.unwrap(), Value::Int(5));
142
143 let expr = Expr::Fn {
145 fn_: "toUpper".to_string(),
146 args: vec![Expr::Const(Value::String("hello".to_string()))],
147 };
148 let result = executor.evaluate_expr(&row, &expr);
149 assert!(result.is_ok());
150 assert_eq!(result.unwrap(), Value::String("HELLO".to_string()));
151 }
152
153 #[test]
154 fn test_conversion_functions() {
155 use execution::executor::QueryExecutor;
156 let executor = QueryExecutor::new();
157
158 let row = Row { values: HashMap::new() };
159
160 let expr = Expr::Fn {
162 fn_: "toString".to_string(),
163 args: vec![Expr::Const(Value::Int(42))],
164 };
165 let result = executor.evaluate_expr(&row, &expr);
166 assert!(result.is_ok());
167 assert_eq!(result.unwrap(), Value::String("42".to_string()));
168
169 let expr = Expr::Fn {
171 fn_: "toInteger".to_string(),
172 args: vec![Expr::Const(Value::String("123".to_string()))],
173 };
174 let result = executor.evaluate_expr(&row, &expr);
175 assert!(result.is_ok());
176 assert_eq!(result.unwrap(), Value::Int(123));
177 }
178}