Skip to main content

graphos_adapters/query/gql/
parser.rs

1//! GQL Parser.
2
3use super::ast::*;
4use super::lexer::{Lexer, Token, TokenKind};
5use graphos_common::utils::error::{Error, QueryError, QueryErrorKind, Result, SourceSpan};
6
7/// GQL Parser.
8pub struct Parser<'a> {
9    lexer: Lexer<'a>,
10    current: Token,
11    source: &'a str,
12}
13
14impl<'a> Parser<'a> {
15    /// Creates a new parser for the given input.
16    pub fn new(input: &'a str) -> Self {
17        let mut lexer = Lexer::new(input);
18        let current = lexer.next_token();
19        Self {
20            lexer,
21            current,
22            source: input,
23        }
24    }
25
26    /// Parses the input into a statement.
27    pub fn parse(&mut self) -> Result<Statement> {
28        match self.current.kind {
29            TokenKind::Match => self.parse_query().map(Statement::Query),
30            TokenKind::Insert => self
31                .parse_insert()
32                .map(|s| Statement::DataModification(DataModificationStatement::Insert(s))),
33            TokenKind::Delete => self
34                .parse_delete()
35                .map(|s| Statement::DataModification(DataModificationStatement::Delete(s))),
36            TokenKind::Create => self.parse_create_schema().map(Statement::Schema),
37            _ => Err(self.error("Expected MATCH, INSERT, DELETE, or CREATE")),
38        }
39    }
40
41    fn parse_query(&mut self) -> Result<QueryStatement> {
42        let span_start = self.current.span.start;
43
44        // Parse MATCH clauses (including OPTIONAL MATCH)
45        let mut match_clauses = Vec::new();
46        while self.current.kind == TokenKind::Match || self.current.kind == TokenKind::Optional {
47            match_clauses.push(self.parse_match_clause()?);
48        }
49
50        // Parse WHERE clause (after all MATCH clauses)
51        let where_clause = if self.current.kind == TokenKind::Where {
52            Some(self.parse_where_clause()?)
53        } else {
54            None
55        };
56
57        // Parse WITH clauses
58        let mut with_clauses = Vec::new();
59        while self.current.kind == TokenKind::With {
60            with_clauses.push(self.parse_with_clause()?);
61
62            // After WITH, we can have more MATCH clauses
63            while self.current.kind == TokenKind::Match || self.current.kind == TokenKind::Optional
64            {
65                match_clauses.push(self.parse_match_clause()?);
66            }
67        }
68
69        // Parse RETURN clause
70        if self.current.kind != TokenKind::Return {
71            return Err(self.error("Expected RETURN"));
72        }
73        let return_clause = self.parse_return_clause()?;
74
75        Ok(QueryStatement {
76            match_clauses,
77            where_clause,
78            with_clauses,
79            return_clause,
80            span: Some(SourceSpan::new(span_start, self.current.span.end, 1, 1)),
81        })
82    }
83
84    fn parse_match_clause(&mut self) -> Result<MatchClause> {
85        let span_start = self.current.span.start;
86
87        // Check for OPTIONAL MATCH
88        let optional = if self.current.kind == TokenKind::Optional {
89            self.advance();
90            true
91        } else {
92            false
93        };
94
95        self.expect(TokenKind::Match)?;
96
97        let mut patterns = Vec::new();
98        patterns.push(self.parse_pattern()?);
99
100        while self.current.kind == TokenKind::Comma {
101            self.advance();
102            patterns.push(self.parse_pattern()?);
103        }
104
105        Ok(MatchClause {
106            optional,
107            patterns,
108            span: Some(SourceSpan::new(span_start, self.current.span.end, 1, 1)),
109        })
110    }
111
112    fn parse_with_clause(&mut self) -> Result<WithClause> {
113        let span_start = self.current.span.start;
114        self.expect(TokenKind::With)?;
115
116        let distinct = if self.current.kind == TokenKind::Distinct {
117            self.advance();
118            true
119        } else {
120            false
121        };
122
123        let mut items = Vec::new();
124        items.push(self.parse_return_item()?);
125
126        while self.current.kind == TokenKind::Comma {
127            self.advance();
128            items.push(self.parse_return_item()?);
129        }
130
131        // Optional WHERE after WITH
132        let where_clause = if self.current.kind == TokenKind::Where {
133            Some(self.parse_where_clause()?)
134        } else {
135            None
136        };
137
138        Ok(WithClause {
139            distinct,
140            items,
141            where_clause,
142            span: Some(SourceSpan::new(span_start, self.current.span.end, 1, 1)),
143        })
144    }
145
146    fn parse_pattern(&mut self) -> Result<Pattern> {
147        let node = self.parse_node_pattern()?;
148
149        // Check for path continuation
150        // Handle both `-[...]->`/`<-[...]-` style and `->` style
151        if matches!(
152            self.current.kind,
153            TokenKind::Arrow | TokenKind::LeftArrow | TokenKind::DoubleDash | TokenKind::Minus
154        ) {
155            let mut edges = Vec::new();
156
157            while matches!(
158                self.current.kind,
159                TokenKind::Arrow | TokenKind::LeftArrow | TokenKind::DoubleDash | TokenKind::Minus
160            ) {
161                edges.push(self.parse_edge_pattern()?);
162            }
163
164            Ok(Pattern::Path(PathPattern {
165                source: node,
166                edges,
167                span: None,
168            }))
169        } else {
170            Ok(Pattern::Node(node))
171        }
172    }
173
174    fn parse_node_pattern(&mut self) -> Result<NodePattern> {
175        self.expect(TokenKind::LParen)?;
176
177        let variable = if self.current.kind == TokenKind::Identifier {
178            let name = self.current.text.clone();
179            self.advance();
180            Some(name)
181        } else {
182            None
183        };
184
185        let mut labels = Vec::new();
186        while self.current.kind == TokenKind::Colon {
187            self.advance();
188            if self.current.kind != TokenKind::Identifier {
189                return Err(self.error("Expected label name"));
190            }
191            labels.push(self.current.text.clone());
192            self.advance();
193        }
194
195        // Parse properties { key: value, ... }
196        let properties = if self.current.kind == TokenKind::LBrace {
197            self.parse_property_map()?
198        } else {
199            Vec::new()
200        };
201
202        self.expect(TokenKind::RParen)?;
203
204        Ok(NodePattern {
205            variable,
206            labels,
207            properties,
208            span: None,
209        })
210    }
211
212    fn parse_edge_pattern(&mut self) -> Result<EdgePattern> {
213        // Handle both styles:
214        // 1. `-[...]->` or `-[:TYPE]->` (direction determined by trailing arrow)
215        // 2. `->` or `<-` or `--` (direction determined by leading arrow)
216
217        let (variable, types, direction) = if self.current.kind == TokenKind::Minus {
218            // Pattern: -[...]->(target) or -[...]-(target)
219            self.advance();
220
221            // Parse [variable:TYPE]
222            let (var, edge_types) = if self.current.kind == TokenKind::LBracket {
223                self.advance();
224
225                let v = if self.current.kind == TokenKind::Identifier
226                    && self.peek_kind() != TokenKind::Colon
227                {
228                    let name = self.current.text.clone();
229                    self.advance();
230                    Some(name)
231                } else {
232                    None
233                };
234
235                let mut tps = Vec::new();
236                while self.current.kind == TokenKind::Colon {
237                    self.advance();
238                    if self.current.kind != TokenKind::Identifier {
239                        return Err(self.error("Expected edge type"));
240                    }
241                    tps.push(self.current.text.clone());
242                    self.advance();
243                }
244
245                self.expect(TokenKind::RBracket)?;
246                (v, tps)
247            } else {
248                (None, Vec::new())
249            };
250
251            // Now determine direction from trailing symbol
252            let dir = if self.current.kind == TokenKind::Arrow {
253                self.advance();
254                EdgeDirection::Outgoing
255            } else if self.current.kind == TokenKind::Minus {
256                self.advance();
257                EdgeDirection::Undirected
258            } else {
259                return Err(self.error("Expected -> or - after edge pattern"));
260            };
261
262            (var, edge_types, dir)
263        } else if self.current.kind == TokenKind::LeftArrow {
264            // Pattern: <-[...]-(target)
265            self.advance();
266
267            let (var, edge_types) = if self.current.kind == TokenKind::LBracket {
268                self.advance();
269
270                let v = if self.current.kind == TokenKind::Identifier
271                    && self.peek_kind() != TokenKind::Colon
272                {
273                    let name = self.current.text.clone();
274                    self.advance();
275                    Some(name)
276                } else {
277                    None
278                };
279
280                let mut tps = Vec::new();
281                while self.current.kind == TokenKind::Colon {
282                    self.advance();
283                    if self.current.kind != TokenKind::Identifier {
284                        return Err(self.error("Expected edge type"));
285                    }
286                    tps.push(self.current.text.clone());
287                    self.advance();
288                }
289
290                self.expect(TokenKind::RBracket)?;
291                (v, tps)
292            } else {
293                (None, Vec::new())
294            };
295
296            // Consume trailing -
297            if self.current.kind == TokenKind::Minus {
298                self.advance();
299            }
300
301            (var, edge_types, EdgeDirection::Incoming)
302        } else if self.current.kind == TokenKind::Arrow {
303            // Simple ->
304            self.advance();
305            (None, Vec::new(), EdgeDirection::Outgoing)
306        } else if self.current.kind == TokenKind::DoubleDash {
307            // Simple --
308            self.advance();
309            (None, Vec::new(), EdgeDirection::Undirected)
310        } else {
311            return Err(self.error("Expected edge pattern"));
312        };
313
314        let target = self.parse_node_pattern()?;
315
316        Ok(EdgePattern {
317            variable,
318            types,
319            direction,
320            target,
321            span: None,
322        })
323    }
324
325    fn parse_where_clause(&mut self) -> Result<WhereClause> {
326        self.expect(TokenKind::Where)?;
327        let expression = self.parse_expression()?;
328
329        Ok(WhereClause {
330            expression,
331            span: None,
332        })
333    }
334
335    fn parse_return_clause(&mut self) -> Result<ReturnClause> {
336        self.expect(TokenKind::Return)?;
337
338        let distinct = if self.current.kind == TokenKind::Distinct {
339            self.advance();
340            true
341        } else {
342            false
343        };
344
345        let mut items = Vec::new();
346        items.push(self.parse_return_item()?);
347
348        while self.current.kind == TokenKind::Comma {
349            self.advance();
350            items.push(self.parse_return_item()?);
351        }
352
353        let order_by = if self.current.kind == TokenKind::Order {
354            Some(self.parse_order_by()?)
355        } else {
356            None
357        };
358
359        let skip = if self.current.kind == TokenKind::Skip {
360            self.advance();
361            Some(self.parse_expression()?)
362        } else {
363            None
364        };
365
366        let limit = if self.current.kind == TokenKind::Limit {
367            self.advance();
368            Some(self.parse_expression()?)
369        } else {
370            None
371        };
372
373        Ok(ReturnClause {
374            distinct,
375            items,
376            order_by,
377            skip,
378            limit,
379            span: None,
380        })
381    }
382
383    fn parse_return_item(&mut self) -> Result<ReturnItem> {
384        let expression = self.parse_expression()?;
385
386        let alias = if self.current.kind == TokenKind::As {
387            self.advance();
388            if self.current.kind != TokenKind::Identifier {
389                return Err(self.error("Expected alias name"));
390            }
391            let name = self.current.text.clone();
392            self.advance();
393            Some(name)
394        } else {
395            None
396        };
397
398        Ok(ReturnItem {
399            expression,
400            alias,
401            span: None,
402        })
403    }
404
405    fn parse_order_by(&mut self) -> Result<OrderByClause> {
406        self.expect(TokenKind::Order)?;
407        self.expect(TokenKind::By)?;
408
409        let mut items = Vec::new();
410        items.push(self.parse_order_item()?);
411
412        while self.current.kind == TokenKind::Comma {
413            self.advance();
414            items.push(self.parse_order_item()?);
415        }
416
417        Ok(OrderByClause { items, span: None })
418    }
419
420    fn parse_order_item(&mut self) -> Result<OrderByItem> {
421        let expression = self.parse_expression()?;
422
423        let order = match self.current.kind {
424            TokenKind::Asc => {
425                self.advance();
426                SortOrder::Asc
427            }
428            TokenKind::Desc => {
429                self.advance();
430                SortOrder::Desc
431            }
432            _ => SortOrder::Asc,
433        };
434
435        Ok(OrderByItem { expression, order })
436    }
437
438    fn parse_expression(&mut self) -> Result<Expression> {
439        self.parse_or_expression()
440    }
441
442    fn parse_or_expression(&mut self) -> Result<Expression> {
443        let mut left = self.parse_and_expression()?;
444
445        while self.current.kind == TokenKind::Or {
446            self.advance();
447            let right = self.parse_and_expression()?;
448            left = Expression::Binary {
449                left: Box::new(left),
450                op: BinaryOp::Or,
451                right: Box::new(right),
452            };
453        }
454
455        Ok(left)
456    }
457
458    fn parse_and_expression(&mut self) -> Result<Expression> {
459        let mut left = self.parse_comparison_expression()?;
460
461        while self.current.kind == TokenKind::And {
462            self.advance();
463            let right = self.parse_comparison_expression()?;
464            left = Expression::Binary {
465                left: Box::new(left),
466                op: BinaryOp::And,
467                right: Box::new(right),
468            };
469        }
470
471        Ok(left)
472    }
473
474    fn parse_comparison_expression(&mut self) -> Result<Expression> {
475        let left = self.parse_additive_expression()?;
476
477        let op = match self.current.kind {
478            TokenKind::Eq => Some(BinaryOp::Eq),
479            TokenKind::Ne => Some(BinaryOp::Ne),
480            TokenKind::Lt => Some(BinaryOp::Lt),
481            TokenKind::Le => Some(BinaryOp::Le),
482            TokenKind::Gt => Some(BinaryOp::Gt),
483            TokenKind::Ge => Some(BinaryOp::Ge),
484            _ => None,
485        };
486
487        if let Some(op) = op {
488            self.advance();
489            let right = self.parse_additive_expression()?;
490            Ok(Expression::Binary {
491                left: Box::new(left),
492                op,
493                right: Box::new(right),
494            })
495        } else {
496            Ok(left)
497        }
498    }
499
500    fn parse_additive_expression(&mut self) -> Result<Expression> {
501        let mut left = self.parse_multiplicative_expression()?;
502
503        loop {
504            let op = match self.current.kind {
505                TokenKind::Plus => BinaryOp::Add,
506                TokenKind::Minus => BinaryOp::Sub,
507                _ => break,
508            };
509            self.advance();
510            let right = self.parse_multiplicative_expression()?;
511            left = Expression::Binary {
512                left: Box::new(left),
513                op,
514                right: Box::new(right),
515            };
516        }
517
518        Ok(left)
519    }
520
521    fn parse_multiplicative_expression(&mut self) -> Result<Expression> {
522        let mut left = self.parse_unary_expression()?;
523
524        loop {
525            let op = match self.current.kind {
526                TokenKind::Star => BinaryOp::Mul,
527                TokenKind::Slash => BinaryOp::Div,
528                TokenKind::Percent => BinaryOp::Mod,
529                _ => break,
530            };
531            self.advance();
532            let right = self.parse_unary_expression()?;
533            left = Expression::Binary {
534                left: Box::new(left),
535                op,
536                right: Box::new(right),
537            };
538        }
539
540        Ok(left)
541    }
542
543    fn parse_unary_expression(&mut self) -> Result<Expression> {
544        match self.current.kind {
545            TokenKind::Not => {
546                self.advance();
547                let operand = self.parse_unary_expression()?;
548                Ok(Expression::Unary {
549                    op: UnaryOp::Not,
550                    operand: Box::new(operand),
551                })
552            }
553            TokenKind::Minus => {
554                self.advance();
555                let operand = self.parse_unary_expression()?;
556                Ok(Expression::Unary {
557                    op: UnaryOp::Neg,
558                    operand: Box::new(operand),
559                })
560            }
561            _ => self.parse_primary_expression(),
562        }
563    }
564
565    fn parse_primary_expression(&mut self) -> Result<Expression> {
566        match self.current.kind {
567            TokenKind::Null => {
568                self.advance();
569                Ok(Expression::Literal(Literal::Null))
570            }
571            TokenKind::True => {
572                self.advance();
573                Ok(Expression::Literal(Literal::Bool(true)))
574            }
575            TokenKind::False => {
576                self.advance();
577                Ok(Expression::Literal(Literal::Bool(false)))
578            }
579            TokenKind::Integer => {
580                let value = self
581                    .current
582                    .text
583                    .parse()
584                    .map_err(|_| self.error("Invalid integer"))?;
585                self.advance();
586                Ok(Expression::Literal(Literal::Integer(value)))
587            }
588            TokenKind::Float => {
589                let value = self
590                    .current
591                    .text
592                    .parse()
593                    .map_err(|_| self.error("Invalid float"))?;
594                self.advance();
595                Ok(Expression::Literal(Literal::Float(value)))
596            }
597            TokenKind::String => {
598                let text = &self.current.text;
599                let value = text[1..text.len() - 1].to_string(); // Remove quotes
600                self.advance();
601                Ok(Expression::Literal(Literal::String(value)))
602            }
603            TokenKind::Identifier => {
604                let name = self.current.text.clone();
605                self.advance();
606
607                if self.current.kind == TokenKind::Dot {
608                    self.advance();
609                    if self.current.kind != TokenKind::Identifier {
610                        return Err(self.error("Expected property name"));
611                    }
612                    let property = self.current.text.clone();
613                    self.advance();
614                    Ok(Expression::PropertyAccess {
615                        variable: name,
616                        property,
617                    })
618                } else if self.current.kind == TokenKind::LParen {
619                    // Function call
620                    self.advance();
621                    let mut args = Vec::new();
622                    if self.current.kind != TokenKind::RParen {
623                        args.push(self.parse_expression()?);
624                        while self.current.kind == TokenKind::Comma {
625                            self.advance();
626                            args.push(self.parse_expression()?);
627                        }
628                    }
629                    self.expect(TokenKind::RParen)?;
630                    Ok(Expression::FunctionCall { name, args })
631                } else {
632                    Ok(Expression::Variable(name))
633                }
634            }
635            TokenKind::LParen => {
636                self.advance();
637                let expr = self.parse_expression()?;
638                self.expect(TokenKind::RParen)?;
639                Ok(expr)
640            }
641            TokenKind::LBracket => {
642                self.advance();
643                let mut elements = Vec::new();
644                if self.current.kind != TokenKind::RBracket {
645                    elements.push(self.parse_expression()?);
646                    while self.current.kind == TokenKind::Comma {
647                        self.advance();
648                        elements.push(self.parse_expression()?);
649                    }
650                }
651                self.expect(TokenKind::RBracket)?;
652                Ok(Expression::List(elements))
653            }
654            TokenKind::Parameter => {
655                // Parameter token includes the $ prefix, so we extract just the name
656                let full_text = &self.current.text;
657                let name = full_text.trim_start_matches('$').to_string();
658                self.advance();
659                Ok(Expression::Parameter(name))
660            }
661            TokenKind::Exists => {
662                self.advance();
663                self.expect(TokenKind::LBrace)?;
664                let inner_query = self.parse_exists_inner_query()?;
665                self.expect(TokenKind::RBrace)?;
666                Ok(Expression::ExistsSubquery {
667                    query: Box::new(inner_query),
668                })
669            }
670            _ => Err(self.error("Expected expression")),
671        }
672    }
673
674    /// Parses the inner query of an EXISTS subquery.
675    /// Handles: EXISTS { MATCH (n)-[:REL]->() [WHERE ...] }
676    fn parse_exists_inner_query(&mut self) -> Result<QueryStatement> {
677        let mut match_clauses = Vec::new();
678
679        // Parse MATCH clauses
680        while self.current.kind == TokenKind::Match || self.current.kind == TokenKind::Optional {
681            match_clauses.push(self.parse_match_clause()?);
682        }
683
684        if match_clauses.is_empty() {
685            return Err(self.error("EXISTS subquery requires at least one MATCH clause"));
686        }
687
688        // Parse optional WHERE
689        let where_clause = if self.current.kind == TokenKind::Where {
690            Some(self.parse_where_clause()?)
691        } else {
692            None
693        };
694
695        // EXISTS doesn't need RETURN - create empty return clause
696        Ok(QueryStatement {
697            match_clauses,
698            where_clause,
699            with_clauses: vec![],
700            return_clause: ReturnClause {
701                distinct: false,
702                items: vec![],
703                order_by: None,
704                skip: None,
705                limit: None,
706                span: None,
707            },
708            span: None,
709        })
710    }
711
712    fn parse_property_map(&mut self) -> Result<Vec<(String, Expression)>> {
713        self.expect(TokenKind::LBrace)?;
714
715        let mut properties = Vec::new();
716
717        if self.current.kind != TokenKind::RBrace {
718            loop {
719                if self.current.kind != TokenKind::Identifier {
720                    return Err(self.error("Expected property name"));
721                }
722                let key = self.current.text.clone();
723                self.advance();
724
725                self.expect(TokenKind::Colon)?;
726
727                let value = self.parse_expression()?;
728                properties.push((key, value));
729
730                if self.current.kind != TokenKind::Comma {
731                    break;
732                }
733                self.advance();
734            }
735        }
736
737        self.expect(TokenKind::RBrace)?;
738        Ok(properties)
739    }
740
741    fn parse_insert(&mut self) -> Result<InsertStatement> {
742        self.expect(TokenKind::Insert)?;
743
744        let mut patterns = Vec::new();
745        patterns.push(self.parse_pattern()?);
746
747        while self.current.kind == TokenKind::Comma {
748            self.advance();
749            patterns.push(self.parse_pattern()?);
750        }
751
752        Ok(InsertStatement {
753            patterns,
754            span: None,
755        })
756    }
757
758    fn parse_delete(&mut self) -> Result<DeleteStatement> {
759        let detach = if self.current.kind == TokenKind::Detach {
760            self.advance();
761            true
762        } else {
763            false
764        };
765
766        self.expect(TokenKind::Delete)?;
767
768        let mut variables = Vec::new();
769        if self.current.kind != TokenKind::Identifier {
770            return Err(self.error("Expected variable name"));
771        }
772        variables.push(self.current.text.clone());
773        self.advance();
774
775        while self.current.kind == TokenKind::Comma {
776            self.advance();
777            if self.current.kind != TokenKind::Identifier {
778                return Err(self.error("Expected variable name"));
779            }
780            variables.push(self.current.text.clone());
781            self.advance();
782        }
783
784        Ok(DeleteStatement {
785            variables,
786            detach,
787            span: None,
788        })
789    }
790
791    fn parse_create_schema(&mut self) -> Result<SchemaStatement> {
792        self.expect(TokenKind::Create)?;
793
794        match self.current.kind {
795            TokenKind::Node => {
796                self.advance();
797                self.expect(TokenKind::Type)?;
798
799                if self.current.kind != TokenKind::Identifier {
800                    return Err(self.error("Expected type name"));
801                }
802                let name = self.current.text.clone();
803                self.advance();
804
805                // Parse property definitions
806                let properties = if self.current.kind == TokenKind::LParen {
807                    self.parse_property_definitions()?
808                } else {
809                    Vec::new()
810                };
811
812                Ok(SchemaStatement::CreateNodeType(CreateNodeTypeStatement {
813                    name,
814                    properties,
815                    span: None,
816                }))
817            }
818            TokenKind::Edge => {
819                self.advance();
820                self.expect(TokenKind::Type)?;
821
822                if self.current.kind != TokenKind::Identifier {
823                    return Err(self.error("Expected type name"));
824                }
825                let name = self.current.text.clone();
826                self.advance();
827
828                let properties = if self.current.kind == TokenKind::LParen {
829                    self.parse_property_definitions()?
830                } else {
831                    Vec::new()
832                };
833
834                Ok(SchemaStatement::CreateEdgeType(CreateEdgeTypeStatement {
835                    name,
836                    properties,
837                    span: None,
838                }))
839            }
840            _ => Err(self.error("Expected NODE or EDGE")),
841        }
842    }
843
844    fn parse_property_definitions(&mut self) -> Result<Vec<PropertyDefinition>> {
845        self.expect(TokenKind::LParen)?;
846
847        let mut defs = Vec::new();
848
849        if self.current.kind != TokenKind::RParen {
850            loop {
851                if self.current.kind != TokenKind::Identifier {
852                    return Err(self.error("Expected property name"));
853                }
854                let name = self.current.text.clone();
855                self.advance();
856
857                if self.current.kind != TokenKind::Identifier {
858                    return Err(self.error("Expected type name"));
859                }
860                let data_type = self.current.text.clone();
861                self.advance();
862
863                let nullable = if self.current.kind == TokenKind::Not {
864                    self.advance();
865                    if self.current.kind != TokenKind::Null {
866                        return Err(self.error("Expected NULL after NOT"));
867                    }
868                    self.advance();
869                    false
870                } else {
871                    true
872                };
873
874                defs.push(PropertyDefinition {
875                    name,
876                    data_type,
877                    nullable,
878                });
879
880                if self.current.kind != TokenKind::Comma {
881                    break;
882                }
883                self.advance();
884            }
885        }
886
887        self.expect(TokenKind::RParen)?;
888        Ok(defs)
889    }
890
891    fn advance(&mut self) {
892        self.current = self.lexer.next_token();
893    }
894
895    fn expect(&mut self, kind: TokenKind) -> Result<()> {
896        if self.current.kind == kind {
897            self.advance();
898            Ok(())
899        } else {
900            Err(self.error(&format!("Expected {:?}", kind)))
901        }
902    }
903
904    fn peek_kind(&mut self) -> TokenKind {
905        // Simple lookahead by creating a temporary lexer
906        // In a production implementation, we'd buffer tokens
907        self.current.kind
908    }
909
910    fn error(&self, message: &str) -> Error {
911        Error::Query(
912            QueryError::new(QueryErrorKind::Syntax, message)
913                .with_span(self.current.span)
914                .with_source(self.source.to_string()),
915        )
916    }
917}
918
919#[cfg(test)]
920mod tests {
921    use super::*;
922
923    #[test]
924    fn test_parse_simple_match() {
925        let mut parser = Parser::new("MATCH (n) RETURN n");
926        let result = parser.parse();
927        assert!(result.is_ok());
928
929        let stmt = result.unwrap();
930        assert!(matches!(stmt, Statement::Query(_)));
931    }
932
933    #[test]
934    fn test_parse_match_with_label() {
935        let mut parser = Parser::new("MATCH (n:Person) RETURN n");
936        let result = parser.parse();
937        assert!(result.is_ok());
938    }
939
940    #[test]
941    fn test_parse_match_with_where() {
942        let mut parser = Parser::new("MATCH (n:Person) WHERE n.age > 30 RETURN n");
943        let result = parser.parse();
944        assert!(result.is_ok());
945    }
946
947    #[test]
948    fn test_parse_path_pattern() {
949        let mut parser = Parser::new("MATCH (a)-[:KNOWS]->(b) RETURN a, b");
950        let result = parser.parse();
951        assert!(result.is_ok());
952    }
953
954    #[test]
955    fn test_parse_insert() {
956        let mut parser = Parser::new("INSERT (n:Person {name: 'Alice'})");
957        let result = parser.parse();
958        assert!(result.is_ok());
959    }
960
961    #[test]
962    fn test_parse_optional_match() {
963        let mut parser =
964            Parser::new("MATCH (a:Person) OPTIONAL MATCH (a)-[:KNOWS]->(b) RETURN a, b");
965        let result = parser.parse();
966        assert!(result.is_ok());
967
968        if let Statement::Query(query) = result.unwrap() {
969            assert_eq!(query.match_clauses.len(), 2);
970            assert!(!query.match_clauses[0].optional);
971            assert!(query.match_clauses[1].optional);
972        } else {
973            panic!("Expected Query statement");
974        }
975    }
976
977    #[test]
978    fn test_parse_with_clause() {
979        let mut parser =
980            Parser::new("MATCH (n:Person) WITH n.name AS name, n.age AS age RETURN name, age");
981        let result = parser.parse();
982        assert!(result.is_ok());
983
984        if let Statement::Query(query) = result.unwrap() {
985            assert_eq!(query.with_clauses.len(), 1);
986            assert_eq!(query.with_clauses[0].items.len(), 2);
987        } else {
988            panic!("Expected Query statement");
989        }
990    }
991
992    #[test]
993    fn test_parse_order_by() {
994        let mut parser = Parser::new("MATCH (n:Person) RETURN n.name ORDER BY n.age DESC");
995        let result = parser.parse();
996        assert!(result.is_ok());
997
998        if let Statement::Query(query) = result.unwrap() {
999            let order_by = query.return_clause.order_by.as_ref().unwrap();
1000            assert_eq!(order_by.items.len(), 1);
1001            assert_eq!(order_by.items[0].order, SortOrder::Desc);
1002        } else {
1003            panic!("Expected Query statement");
1004        }
1005    }
1006
1007    #[test]
1008    fn test_parse_limit_skip() {
1009        let mut parser = Parser::new("MATCH (n) RETURN n SKIP 10 LIMIT 5");
1010        let result = parser.parse();
1011        assert!(result.is_ok());
1012
1013        if let Statement::Query(query) = result.unwrap() {
1014            assert!(query.return_clause.skip.is_some());
1015            assert!(query.return_clause.limit.is_some());
1016        } else {
1017            panic!("Expected Query statement");
1018        }
1019    }
1020
1021    #[test]
1022    fn test_parse_aggregation() {
1023        let mut parser = Parser::new("MATCH (n:Person) RETURN count(n), avg(n.age)");
1024        let result = parser.parse();
1025        assert!(result.is_ok());
1026
1027        if let Statement::Query(query) = result.unwrap() {
1028            assert_eq!(query.return_clause.items.len(), 2);
1029            // Check that function calls are parsed
1030            if let Expression::FunctionCall { name, .. } = &query.return_clause.items[0].expression
1031            {
1032                assert_eq!(name, "count");
1033            } else {
1034                panic!("Expected function call");
1035            }
1036        } else {
1037            panic!("Expected Query statement");
1038        }
1039    }
1040
1041    #[test]
1042    fn test_parse_with_parameter() {
1043        let mut parser = Parser::new("MATCH (n:Person) WHERE n.age > $min_age RETURN n");
1044        let result = parser.parse();
1045        assert!(result.is_ok());
1046
1047        if let Statement::Query(query) = result.unwrap() {
1048            // Check that the WHERE clause contains a parameter
1049            let where_clause = query.where_clause.as_ref().expect("Expected WHERE clause");
1050            if let Expression::Binary { right, .. } = &where_clause.expression {
1051                if let Expression::Parameter(name) = right.as_ref() {
1052                    assert_eq!(name, "min_age");
1053                } else {
1054                    panic!("Expected parameter, got {:?}", right);
1055                }
1056            } else {
1057                panic!("Expected binary expression in WHERE clause");
1058            }
1059        } else {
1060            panic!("Expected Query statement");
1061        }
1062    }
1063
1064    #[test]
1065    fn test_parse_insert_with_parameter() {
1066        let mut parser = Parser::new("INSERT (n:Person {name: $name, age: $age})");
1067        let result = parser.parse();
1068        assert!(result.is_ok());
1069
1070        if let Statement::DataModification(DataModificationStatement::Insert(insert)) =
1071            result.unwrap()
1072        {
1073            if let Pattern::Node(node) = &insert.patterns[0] {
1074                assert_eq!(node.properties.len(), 2);
1075                // Check first property is a parameter
1076                if let Expression::Parameter(name) = &node.properties[0].1 {
1077                    assert_eq!(name, "name");
1078                } else {
1079                    panic!("Expected parameter for name property");
1080                }
1081            } else {
1082                panic!("Expected node pattern");
1083            }
1084        } else {
1085            panic!("Expected Insert statement");
1086        }
1087    }
1088}