kotoba_query_engine/
ast.rs

1//! Abstract Syntax Tree for ISO GQL
2//!
3//! This module defines the AST structures for ISO GQL queries and statements.
4
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8/// Main query structure
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct GqlQuery {
11    pub clauses: Vec<QueryClause>,
12    pub returning: Option<ReturnClause>,
13}
14
15/// Query clauses in order
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub enum QueryClause {
18    Match(MatchClause),
19    Where(WhereClause),
20    GroupBy(GroupByClause),
21    Having(HavingClause),
22    OrderBy(OrderByClause),
23    Limit(LimitClause),
24}
25
26/// MATCH clause for graph pattern matching
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct MatchClause {
29    pub optional: bool,
30    pub pattern: GraphPattern,
31}
32
33/// Graph pattern consisting of path patterns
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct GraphPattern {
36    pub path_patterns: Vec<PathPattern>,
37}
38
39/// Path pattern for matching paths in the graph
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct PathPattern {
42    pub variable: Option<String>,
43    pub path_term: PathTerm,
44}
45
46/// Path term (simplified for basic implementation)
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub enum PathTerm {
49    PathElement(PathElement),
50    PathConcatenation(Box<PathTerm>, Box<PathTerm>),
51}
52
53/// Path element consisting of vertex and edge patterns
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct PathElement {
56    pub vertex_pattern: VertexPattern,
57    pub edge_patterns: Vec<EdgePattern>,
58}
59
60/// Vertex pattern for matching vertices
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct VertexPattern {
63    pub variable: Option<String>,
64    pub labels: Vec<String>,
65    pub properties: HashMap<String, ValueExpression>,
66}
67
68/// Edge pattern for matching edges
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct EdgePattern {
71    pub variable: Option<String>,
72    pub direction: EdgeDirection,
73    pub labels: Vec<String>,
74    pub properties: HashMap<String, ValueExpression>,
75    pub quantifier: Option<PathQuantifier>,
76}
77
78/// Edge direction
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub enum EdgeDirection {
81    Left,   // <- or <-- (incoming)
82    Right,  // -> or --> (outgoing)
83    Both,   // - or -- (undirected)
84}
85
86/// Path quantifier for variable-length paths
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct PathQuantifier {
89    pub min: Option<u32>,
90    pub max: Option<u32>,
91}
92
93/// WHERE clause for filtering
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct WhereClause {
96    pub expression: BooleanExpression,
97}
98
99/// Boolean expression for WHERE conditions
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub enum BooleanExpression {
102    And(Box<BooleanExpression>, Box<BooleanExpression>),
103    Or(Box<BooleanExpression>, Box<BooleanExpression>),
104    Not(Box<BooleanExpression>),
105    Comparison(ComparisonExpression),
106    Exists(Box<GraphPattern>),
107}
108
109/// Comparison expression
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct ComparisonExpression {
112    pub left: Box<ValueExpression>,
113    pub operator: ComparisonOperator,
114    pub right: Box<ValueExpression>,
115}
116
117/// Comparison operators
118#[derive(Debug, Clone, Serialize, Deserialize)]
119pub enum ComparisonOperator {
120    Equal,
121    NotEqual,
122    LessThan,
123    LessThanOrEqual,
124    GreaterThan,
125    GreaterThanOrEqual,
126    Like,
127    Regex,
128}
129
130/// Value expression
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub enum ValueExpression {
133    Literal(AstValue),
134    Variable(String),
135    PropertyAccess(Box<ValueExpression>, String),
136    FunctionCall(FunctionCall),
137    Arithmetic(ArithmeticExpression),
138}
139
140/// Arithmetic expression
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct ArithmeticExpression {
143    pub left: Box<ValueExpression>,
144    pub operator: ArithmeticOperator,
145    pub right: Box<ValueExpression>,
146}
147
148/// Arithmetic operators
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub enum ArithmeticOperator {
151    Add,
152    Subtract,
153    Multiply,
154    Divide,
155    Modulo,
156}
157
158/// Function call
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct FunctionCall {
161    pub function_name: String,
162    pub arguments: Vec<ValueExpression>,
163}
164
165/// Value types for literals
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub enum AstValue {
168    Null,
169    Boolean(bool),
170    Integer(i64),
171    Float(f64),
172    String(String),
173    List(Vec<AstValue>),
174    Map(HashMap<String, AstValue>),
175}
176
177/// RETURN clause
178#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct ReturnClause {
180    pub distinct: bool,
181    pub items: Vec<ReturnItem>,
182}
183
184/// Return item
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct ReturnItem {
187    pub expression: ValueExpression,
188    pub alias: Option<String>,
189}
190
191/// GROUP BY clause
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct GroupByClause {
194    pub grouping_keys: Vec<ValueExpression>,
195}
196
197/// HAVING clause
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct HavingClause {
200    pub expression: BooleanExpression,
201}
202
203/// ORDER BY clause
204#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct OrderByClause {
206    pub sort_keys: Vec<SortKey>,
207}
208
209/// Sort key
210#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct SortKey {
212    pub expression: ValueExpression,
213    pub direction: SortDirection,
214}
215
216/// Sort direction
217#[derive(Debug, Clone, Serialize, Deserialize)]
218pub enum SortDirection {
219    Ascending,
220    Descending,
221}
222
223/// LIMIT clause
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct LimitClause {
226    pub count: u64,
227    pub offset: Option<u64>,
228}
229
230/// DDL Statements
231#[derive(Debug, Clone, Serialize, Deserialize)]
232pub enum GqlStatement {
233    CreateGraph(CreateGraphStatement),
234    DropGraph(DropGraphStatement),
235    CreateVertex(CreateVertexStatement),
236    CreateEdge(CreateEdgeStatement),
237    Insert(InsertStatement),
238}
239
240/// CREATE GRAPH statement
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct CreateGraphStatement {
243    pub graph_name: String,
244    pub if_not_exists: bool,
245}
246
247/// DROP GRAPH statement
248#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct DropGraphStatement {
250    pub graph_name: String,
251    pub if_exists: bool,
252}
253
254/// CREATE VERTEX statement
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct CreateVertexStatement {
257    pub labels: Vec<String>,
258    pub properties: HashMap<String, ValueExpression>,
259}
260
261/// CREATE EDGE statement
262#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct CreateEdgeStatement {
264    pub label: String,
265    pub from_vertex: VertexPattern,
266    pub to_vertex: VertexPattern,
267    pub properties: HashMap<String, ValueExpression>,
268}
269
270/// INSERT statement
271#[derive(Debug, Clone, Serialize, Deserialize)]
272pub struct InsertStatement {
273    pub vertex_inserts: Vec<VertexInsert>,
274    pub edge_inserts: Vec<EdgeInsert>,
275}
276
277/// Vertex insert
278#[derive(Debug, Clone, Serialize, Deserialize)]
279pub struct VertexInsert {
280    pub variable: Option<String>,
281    pub labels: Vec<String>,
282    pub properties: HashMap<String, ValueExpression>,
283}
284
285/// Edge insert
286#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct EdgeInsert {
288    pub variable: Option<String>,
289    pub label: String,
290    pub from_vertex: String,
291    pub to_vertex: String,
292    pub properties: HashMap<String, ValueExpression>,
293}
294
295#[cfg(test)]
296mod tests {
297    use super::*;
298
299    #[test]
300    fn test_simple_match_query() {
301        // Test parsing a simple MATCH query
302        // This would be expanded with actual parser tests
303        let vertex_pattern = VertexPattern {
304            variable: Some("v".to_string()),
305            labels: vec!["Person".to_string()],
306            properties: HashMap::new(),
307        };
308
309        let path_element = PathElement {
310            vertex_pattern,
311            edge_patterns: Vec::new(),
312        };
313
314        let path_pattern = PathPattern {
315            variable: None,
316            path_term: PathTerm::PathElement(path_element),
317        };
318
319        let match_clause = MatchClause {
320            optional: false,
321            pattern: GraphPattern {
322                path_patterns: vec![path_pattern],
323            },
324        };
325
326        let query = GqlQuery {
327            clauses: vec![QueryClause::Match(match_clause)],
328            returning: Some(ReturnClause {
329                distinct: false,
330                items: vec![ReturnItem {
331                    expression: ValueExpression::Variable("v".to_string()),
332                    alias: None,
333                }],
334            }),
335        };
336
337        // Verify structure
338        assert_eq!(query.clauses.len(), 1);
339        if let QueryClause::Match(ref match_clause) = &query.clauses[0] {
340            assert!(!match_clause.optional);
341            assert_eq!(match_clause.pattern.path_patterns.len(), 1);
342        }
343    }
344}