reddb_server/storage/query/parser/
tree.rs1use super::super::ast::{
4 CreateTreeQuery, DropTreeQuery, QueryExpr, TreeCommand, TreeNodeSpec, TreePosition,
5};
6use super::super::lexer::Token;
7use super::error::ParseError;
8use super::Parser;
9use crate::json::Value as JsonValue;
10use crate::storage::schema::Value;
11
12impl<'a> Parser<'a> {
13 pub fn parse_create_tree_body(&mut self) -> Result<QueryExpr, ParseError> {
14 let if_not_exists = self.match_if_not_exists()?;
15 let name = self.expect_ident()?;
16 self.expect(Token::In)?;
17 let collection = self.expect_ident()?;
18 self.expect_tree_ident("ROOT")?;
19 let root = self.parse_tree_node_spec(false)?;
20 let default_max_children = self.parse_tree_required_max_children()?;
21
22 Ok(QueryExpr::CreateTree(CreateTreeQuery {
23 collection,
24 name,
25 root,
26 default_max_children,
27 if_not_exists,
28 }))
29 }
30
31 pub fn parse_drop_tree_body(&mut self) -> Result<QueryExpr, ParseError> {
32 let if_exists = self.match_if_exists()?;
33 let name = self.expect_ident()?;
34 self.expect(Token::In)?;
35 let collection = self.expect_ident()?;
36 Ok(QueryExpr::DropTree(DropTreeQuery {
37 collection,
38 name,
39 if_exists,
40 }))
41 }
42
43 pub fn parse_tree_command(&mut self) -> Result<QueryExpr, ParseError> {
44 self.expect(Token::Tree)?;
45
46 if self.consume(&Token::Insert)? {
47 self.expect(Token::Into)?;
48 let (collection, tree_name) = self.parse_tree_target()?;
49 self.expect_tree_ident("PARENT")?;
50 let parent_id = self.parse_tree_entity_id()?;
51 let node = self.parse_tree_node_spec(true)?;
52 let position = self.parse_tree_position()?;
53 return Ok(QueryExpr::TreeCommand(TreeCommand::Insert {
54 collection,
55 tree_name,
56 parent_id,
57 node,
58 position,
59 }));
60 }
61
62 if self.consume_ident_ci("MOVE")? {
63 let (collection, tree_name) = self.parse_tree_target()?;
64 self.expect(Token::Node)?;
65 let node_id = self.parse_tree_entity_id()?;
66 self.expect(Token::To)?;
67 self.expect_tree_ident("PARENT")?;
68 let parent_id = self.parse_tree_entity_id()?;
69 let position = self.parse_tree_position()?;
70 return Ok(QueryExpr::TreeCommand(TreeCommand::Move {
71 collection,
72 tree_name,
73 node_id,
74 parent_id,
75 position,
76 }));
77 }
78
79 if self.consume(&Token::Delete)? {
80 let (collection, tree_name) = self.parse_tree_target()?;
81 self.expect(Token::Node)?;
82 let node_id = self.parse_tree_entity_id()?;
83 return Ok(QueryExpr::TreeCommand(TreeCommand::Delete {
84 collection,
85 tree_name,
86 node_id,
87 }));
88 }
89
90 if self.consume_ident_ci("VALIDATE")? {
91 let (collection, tree_name) = self.parse_tree_target()?;
92 return Ok(QueryExpr::TreeCommand(TreeCommand::Validate {
93 collection,
94 tree_name,
95 }));
96 }
97
98 if self.consume_ident_ci("REBALANCE")? {
99 let (collection, tree_name) = self.parse_tree_target()?;
100 let dry_run = if self.consume_ident_ci("DRY")? {
101 self.expect_tree_ident("RUN")?;
102 true
103 } else {
104 false
105 };
106 return Ok(QueryExpr::TreeCommand(TreeCommand::Rebalance {
107 collection,
108 tree_name,
109 dry_run,
110 }));
111 }
112
113 Err(ParseError::expected(
114 vec!["INSERT", "MOVE", "DELETE", "VALIDATE", "REBALANCE"],
115 self.peek(),
116 self.position(),
117 ))
118 }
119
120 fn parse_tree_target(&mut self) -> Result<(String, String), ParseError> {
121 let collection = self.expect_ident()?;
122 self.expect(Token::Dot)?;
123 let tree_name = self.expect_ident()?;
124 Ok((collection, tree_name))
125 }
126
127 fn parse_tree_node_spec(
128 &mut self,
129 allow_max_children: bool,
130 ) -> Result<TreeNodeSpec, ParseError> {
131 self.expect_tree_ident("LABEL")?;
132 let label = self.parse_tree_string_like()?;
133 let mut node_type = None;
134 let mut properties = Vec::new();
135 let mut metadata = Vec::new();
136 let mut max_children = None;
137
138 loop {
139 if self.consume_ident_ci("TYPE")? {
140 node_type = Some(self.parse_tree_string_like()?);
141 } else if self.consume(&Token::Properties)? {
142 properties = self.parse_tree_object_literal_entries()?;
143 } else if self.consume(&Token::Metadata)? {
144 metadata = self.parse_tree_object_literal_entries()?;
145 } else if allow_max_children
146 && (self.consume_ident_ci("MAX_CHILDREN")?
147 || self.consume_ident_ci("MAXCHILDREN")?)
148 {
149 max_children = Some(self.parse_tree_positive_usize()?);
150 } else {
151 break;
152 }
153 }
154
155 Ok(TreeNodeSpec {
156 label,
157 node_type,
158 properties,
159 metadata,
160 max_children,
161 })
162 }
163
164 fn parse_tree_position(&mut self) -> Result<TreePosition, ParseError> {
165 if !(self.consume_ident_ci("POSITION")?) {
166 return Ok(TreePosition::Last);
167 }
168
169 if self.consume(&Token::First)? {
170 return Ok(TreePosition::First);
171 }
172 if self.consume(&Token::Last)? {
173 return Ok(TreePosition::Last);
174 }
175
176 Ok(TreePosition::Index(self.parse_tree_positive_usize()?))
177 }
178
179 fn parse_tree_required_max_children(&mut self) -> Result<usize, ParseError> {
180 if !(self.consume_ident_ci("MAX_CHILDREN")? || self.consume_ident_ci("MAXCHILDREN")?) {
181 return Err(ParseError::expected(
182 vec!["MAX_CHILDREN"],
183 self.peek(),
184 self.position(),
185 ));
186 }
187 self.parse_tree_positive_usize()
188 }
189
190 fn parse_tree_entity_id(&mut self) -> Result<u64, ParseError> {
191 match self.peek().clone() {
192 Token::Integer(value) if value > 0 => {
193 self.advance()?;
194 Ok(value as u64)
195 }
196 Token::String(value) => {
197 self.advance()?;
198 parse_tree_entity_id_text(&value).ok_or_else(|| {
199 ParseError::new(
200 format!("invalid tree entity id {value:?}"),
205 self.position(),
206 )
207 })
208 }
209 other => Err(ParseError::expected(
210 vec!["entity id"],
211 &other,
212 self.position(),
213 )),
214 }
215 }
216
217 fn parse_tree_positive_usize(&mut self) -> Result<usize, ParseError> {
218 let value = self.parse_integer()?;
219 if value <= 0 {
220 return Err(ParseError::new(
221 "expected a positive integer".to_string(),
222 self.position(),
223 ));
224 }
225 Ok(value as usize)
226 }
227
228 fn parse_tree_string_like(&mut self) -> Result<String, ParseError> {
229 match self.peek().clone() {
230 Token::String(value) => {
231 self.advance()?;
232 Ok(value)
233 }
234 _ => self.expect_ident_or_keyword(),
235 }
236 }
237
238 fn expect_tree_ident(&mut self, expected: &str) -> Result<(), ParseError> {
239 if self.consume_ident_ci(expected)? {
240 return Ok(());
241 }
242 Err(ParseError::expected(
243 vec![expected],
244 self.peek(),
245 self.position(),
246 ))
247 }
248
249 fn parse_tree_object_literal_entries(&mut self) -> Result<Vec<(String, Value)>, ParseError> {
250 let literal = self.parse_literal_value()?;
251 let Value::Json(bytes) = literal else {
252 return Err(ParseError::new(
253 "expected object literal".to_string(),
254 self.position(),
255 ));
256 };
257 let decoded = crate::json::from_slice::<JsonValue>(&bytes).map_err(|err| {
258 ParseError::new(
259 format!("failed to decode object literal: {:?}", err.to_string()),
263 self.position(),
264 )
265 })?;
266 let JsonValue::Object(object) = decoded else {
267 return Err(ParseError::new(
268 "expected object literal".to_string(),
269 self.position(),
270 ));
271 };
272 object
273 .into_iter()
274 .map(|(key, value)| Ok((key, tree_json_value_to_storage_value(&value)?)))
275 .collect()
276 }
277}
278
279fn parse_tree_entity_id_text(value: &str) -> Option<u64> {
280 value
281 .strip_prefix('e')
282 .unwrap_or(value)
283 .parse::<u64>()
284 .ok()
285 .filter(|value| *value > 0)
286}
287
288fn tree_json_value_to_storage_value(value: &JsonValue) -> Result<Value, ParseError> {
289 Ok(match value {
290 JsonValue::Null => Value::Null,
291 JsonValue::Bool(value) => Value::Boolean(*value),
292 JsonValue::Number(value) => {
293 if value.fract().abs() < f64::EPSILON {
294 Value::Integer(*value as i64)
295 } else {
296 Value::Float(*value)
297 }
298 }
299 JsonValue::String(value) => Value::text(value.clone()),
300 JsonValue::Array(_) | JsonValue::Object(_) => {
301 Value::Json(crate::json::to_vec(value).map_err(|err| {
302 ParseError::new(
303 format!("failed to encode nested JSON value: {:?}", err.to_string()),
306 crate::storage::query::lexer::Position::default(),
307 )
308 })?)
309 }
310 })
311}