Convert a path pattern to logical plan nodes
(pattern: &PathPattern)
| 341 | |
| 342 | /// Convert a path pattern to logical plan nodes |
| 343 | pub fn from_path_pattern(pattern: &PathPattern) -> Result<LogicalNode, String> { |
| 344 | if pattern.elements.is_empty() { |
| 345 | return Err("Empty path pattern".to_string()); |
| 346 | } |
| 347 | |
| 348 | // If path type is specified and not WALK, use PathTraversal |
| 349 | if let Some(path_type) = &pattern.path_type { |
| 350 | if *path_type != PathType::Walk { |
| 351 | return Self::create_path_traversal(pattern, path_type.clone()); |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | let mut current_node: Option<LogicalNode> = None; |
| 356 | let mut i = 0; |
| 357 | |
| 358 | while i < pattern.elements.len() { |
| 359 | match &pattern.elements[i] { |
| 360 | PatternElement::Node(node) => { |
| 361 | let variable = node |
| 362 | .identifier |
| 363 | .clone() |
| 364 | .unwrap_or_else(|| format!("_node_{}", i)); |
| 365 | |
| 366 | let node_scan = LogicalNode::NodeScan { |
| 367 | variable: variable.clone(), |
| 368 | labels: node.labels.clone(), |
| 369 | properties: node.properties.as_ref().map(|props| { |
| 370 | props |
| 371 | .properties |
| 372 | .iter() |
| 373 | .map(|p| (p.key.clone(), p.value.clone())) |
| 374 | .collect() |
| 375 | }), |
| 376 | }; |
| 377 | |
| 378 | if current_node.is_none() { |
| 379 | current_node = Some(node_scan); |
| 380 | } |
| 381 | |
| 382 | // Look ahead for edge pattern |
| 383 | if i + 1 < pattern.elements.len() { |
| 384 | if let PatternElement::Edge(edge) = &pattern.elements[i + 1] { |
| 385 | // Look ahead for next node |
| 386 | if i + 2 < pattern.elements.len() { |
| 387 | if let PatternElement::Node(next_node) = &pattern.elements[i + 2] { |
| 388 | let edge_variable = edge.identifier.clone(); |
| 389 | let to_variable = next_node |
| 390 | .identifier |
| 391 | .clone() |
| 392 | .unwrap_or_else(|| format!("_node_{}", i + 2)); |
| 393 | |
| 394 | let expand = LogicalNode::Expand { |
| 395 | from_variable: variable, |
| 396 | edge_variable, |
| 397 | to_variable: to_variable.clone(), |
| 398 | edge_labels: edge.labels.clone(), |
| 399 | direction: edge.direction.clone(), |
| 400 | properties: edge.properties.as_ref().map(|props| { |