reddb_server/storage/query/parser/
path.rs1use super::super::ast::{CompareOp, NodeSelector, PathQuery, PropertyFilter, QueryExpr};
4use super::super::lexer::Token;
5use super::error::ParseError;
6use super::Parser;
7
8impl<'a> Parser<'a> {
9 pub fn parse_path_query(&mut self) -> Result<QueryExpr, ParseError> {
11 self.expect(Token::Path)?;
12 self.expect(Token::From)?;
13
14 let from = self.parse_node_selector()?;
15
16 self.expect(Token::To)?;
17
18 let to = self.parse_node_selector()?;
19
20 let via = if self.consume(&Token::Via)? {
21 self.parse_edge_type_list()?
22 } else {
23 Vec::new()
24 };
25
26 let mut max_length = 10;
27 loop {
28 if self.consume(&Token::Algorithm)? || self.consume(&Token::Direction)? {
29 let _ = self.expect_ident_or_keyword()?;
30 } else if self.consume(&Token::Limit)? {
31 max_length = self.parse_integer()? as u32;
32 } else {
33 break;
34 }
35 }
36
37 let filter = if self.consume(&Token::Where)? {
38 Some(self.parse_filter()?)
39 } else {
40 None
41 };
42
43 let return_ = if self.consume(&Token::Return)? {
44 self.parse_return_list()?
45 } else {
46 Vec::new()
47 };
48
49 Ok(QueryExpr::Path(PathQuery {
50 alias: None,
51 from,
52 to,
53 via,
54 max_length,
55 filter,
56 return_,
57 }))
58 }
59
60 fn parse_node_selector(&mut self) -> Result<NodeSelector, ParseError> {
62 if let Token::String(id) = self.peek().clone() {
63 self.advance()?;
64 return Ok(NodeSelector::ById(id));
65 }
66
67 let name = self.expect_ident()?;
68
69 if !self.consume(&Token::LParen)? {
70 return Ok(NodeSelector::ById(name));
71 }
72
73 let selector = match name.to_lowercase().as_str() {
74 "host" | "node" | "id" => {
75 let id = self.parse_string()?;
76 NodeSelector::ById(id)
77 }
78 "row" => {
79 let table = self.parse_string()?;
80 self.expect(Token::Comma)?;
81 let row_id = self.parse_integer()? as u64;
82 NodeSelector::ByRow { table, row_id }
83 }
84 type_name => {
85 let node_label = self.parse_node_label(type_name)?;
87 let filter = if !self.check(&Token::RParen) {
88 let name = self.expect_ident()?;
89 self.expect(Token::Eq)?;
90 let value = self.parse_value()?;
91 Some(PropertyFilter {
92 name,
93 op: CompareOp::Eq,
94 value,
95 })
96 } else {
97 None
98 };
99 NodeSelector::ByType { node_label, filter }
100 }
101 };
102
103 self.expect(Token::RParen)?;
104
105 Ok(selector)
106 }
107
108 fn parse_edge_type_list(&mut self) -> Result<Vec<String>, ParseError> {
110 self.expect(Token::LBracket)?;
111
112 let mut labels = Vec::new();
113 loop {
114 self.expect(Token::Colon)?;
115 let type_name = self.expect_ident_or_keyword()?;
116 labels.push(self.parse_edge_label(&type_name)?);
117
118 if !self.consume(&Token::Comma)? {
119 break;
120 }
121 }
122
123 self.expect(Token::RBracket)?;
124 Ok(labels)
125 }
126}