A Claude-written graph database in Rust. Use at your own risk.
at main 834 lines 37 kB view raw
1use crate::cypher::planner::{QueryPlan, ScanPlan, CreatePlan, ProjectPlan}; 2use crate::cypher::ast::{CypherQuery, MatchClause, CreateClause, ReturnClause, Expression, PatternElement}; 3use crate::core::{Graph, PropertyValue}; 4use crate::index::{IndexQuery, IndexType}; 5use crate::{Result, GigabrainError, NodeId, RelationshipId}; 6use std::sync::Arc; 7use std::collections::HashMap; 8use tracing::{debug, info}; 9 10pub struct QueryExecutor { 11 graph: Arc<Graph>, 12} 13 14impl QueryExecutor { 15 pub fn new(graph: Arc<Graph>) -> Self { 16 Self { graph } 17 } 18 19 pub async fn execute_query(&self, query: &CypherQuery) -> Result<QueryResult> { 20 match query { 21 CypherQuery::Match(match_clause) => self.execute_match(match_clause).await, 22 CypherQuery::Create(create_clause) => self.execute_create_query(create_clause).await, 23 CypherQuery::Return(return_clause) => self.execute_return(return_clause).await, 24 CypherQuery::Compound(queries) => { 25 let mut context = ExecutionContext::new(); 26 for query in queries { 27 let _result = self.execute_query_with_context(query, &mut context).await?; 28 // Store intermediate results in context for compound queries 29 } 30 Ok(context.into_result()) 31 }, 32 _ => Err(GigabrainError::Query("Query type not supported yet".to_string())), 33 } 34 } 35 36 fn execute_query_with_context<'a>(&'a self, query: &'a CypherQuery, context: &'a mut ExecutionContext) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<QueryResult>> + 'a>> { 37 Box::pin(async move { 38 match query { 39 CypherQuery::Match(match_clause) => { 40 let result = self.execute_match_with_context(match_clause, context).await?; 41 context.merge_result(result); 42 Ok(QueryResult::empty()) 43 }, 44 CypherQuery::Return(return_clause) => { 45 self.execute_return_with_context(return_clause, context).await 46 }, 47 _ => self.execute_query(query).await, 48 } 49 }) 50 } 51 52 async fn execute_match(&self, match_clause: &MatchClause) -> Result<QueryResult> { 53 let mut context = ExecutionContext::new(); 54 self.execute_match_with_context(match_clause, &mut context).await?; 55 56 // Return all matched nodes directly 57 let all_nodes = self.graph.get_all_nodes(); 58 let columns = vec!["n".to_string()]; 59 let mut rows = Vec::new(); 60 61 for node_id in all_nodes { 62 rows.push(Row { 63 values: vec![Value::Node(node_id)] 64 }); 65 } 66 67 Ok(QueryResult { rows, columns }) 68 } 69 70 async fn execute_match_with_context(&self, match_clause: &MatchClause, context: &mut ExecutionContext) -> Result<QueryResult> { 71 // Simple pattern matching for demonstration 72 // In reality, this would use a sophisticated query planner 73 74 let pattern = &match_clause.pattern; 75 76 // Process pattern elements sequentially 77 let mut i = 0; 78 while i < pattern.elements.len() { 79 match &pattern.elements[i] { 80 PatternElement::Node(node_pattern) => { 81 if let Some(variable) = &node_pattern.variable { 82 // Get nodes matching the pattern 83 let matching_nodes = self.find_matching_nodes(node_pattern).await?; 84 context.bind_variable(variable.clone(), VariableBinding::Nodes(matching_nodes)); 85 } 86 i += 1; 87 }, 88 PatternElement::Relationship(rel_pattern) => { 89 // Handle relationship patterns 90 if let Some(variable) = &rel_pattern.variable { 91 // For now, get all relationships 92 // TODO: Implement proper relationship matching based on type and direction 93 let all_relationships = self.get_all_relationships().await?; 94 context.bind_variable(variable.clone(), VariableBinding::Relationships(all_relationships)); 95 } 96 i += 1; 97 }, 98 _ => { 99 i += 1; 100 } 101 } 102 } 103 104 // Apply WHERE clause filtering if present 105 if let Some(where_expr) = &match_clause.where_clause { 106 self.apply_where_filter(context, where_expr).await?; 107 } 108 109 Ok(QueryResult::empty()) 110 } 111 112 async fn apply_where_filter(&self, context: &mut ExecutionContext, where_expr: &Expression) -> Result<()> { 113 // Create a new context to store filtered results 114 let mut filtered_context = ExecutionContext::new(); 115 116 // For each variable binding, evaluate the WHERE clause 117 let variable_names: Vec<String> = context.variables.keys().cloned().collect(); 118 119 if variable_names.is_empty() { 120 return Ok(()); 121 } 122 123 // Get all possible combinations of variable bindings 124 let combinations = self.generate_binding_combinations(context).await?; 125 126 // Filter combinations based on WHERE clause 127 let mut filtered_combinations = Vec::new(); 128 for combination in combinations { 129 // Create a temporary context with this specific binding combination 130 let mut temp_context = ExecutionContext::new(); 131 for (var_name, binding) in &combination { 132 temp_context.bind_variable(var_name.clone(), binding.clone()); 133 } 134 135 // Evaluate WHERE clause with this binding 136 let result = self.evaluate_expression(where_expr, &temp_context, None).await?; 137 138 if self.is_truthy(&result) { 139 filtered_combinations.push(combination); 140 } 141 } 142 143 // Rebuild the context with filtered results 144 self.rebuild_context_from_combinations(context, filtered_combinations); 145 146 Ok(()) 147 } 148 149 async fn generate_binding_combinations(&self, context: &ExecutionContext) -> Result<Vec<HashMap<String, VariableBinding>>> { 150 let mut combinations = Vec::new(); 151 let variable_names: Vec<String> = context.variables.keys().cloned().collect(); 152 153 if variable_names.is_empty() { 154 return Ok(combinations); 155 } 156 157 // Generate all combinations of variable bindings 158 // This is a simplified approach - for performance, we'd use join algorithms 159 if variable_names.len() == 1 { 160 let var_name = &variable_names[0]; 161 if let Some(binding) = context.variables.get(var_name) { 162 match binding { 163 VariableBinding::Nodes(node_ids) => { 164 for &node_id in node_ids { 165 let mut combination = HashMap::new(); 166 combination.insert(var_name.clone(), VariableBinding::Nodes(vec![node_id])); 167 combinations.push(combination); 168 } 169 }, 170 VariableBinding::Relationships(rel_ids) => { 171 for &rel_id in rel_ids { 172 let mut combination = HashMap::new(); 173 combination.insert(var_name.clone(), VariableBinding::Relationships(vec![rel_id])); 174 combinations.push(combination); 175 } 176 } 177 } 178 } 179 } else { 180 // For multiple variables, generate cartesian product 181 // This is simplified - real implementation would be more efficient 182 self.generate_cartesian_product(context, &variable_names, 0, &mut HashMap::new(), &mut combinations); 183 } 184 185 Ok(combinations) 186 } 187 188 fn generate_cartesian_product( 189 &self, 190 context: &ExecutionContext, 191 variable_names: &[String], 192 index: usize, 193 current_combination: &mut HashMap<String, VariableBinding>, 194 combinations: &mut Vec<HashMap<String, VariableBinding>> 195 ) { 196 if index >= variable_names.len() { 197 combinations.push(current_combination.clone()); 198 return; 199 } 200 201 let var_name = &variable_names[index]; 202 if let Some(binding) = context.variables.get(var_name) { 203 match binding { 204 VariableBinding::Nodes(node_ids) => { 205 for &node_id in node_ids { 206 current_combination.insert(var_name.clone(), VariableBinding::Nodes(vec![node_id])); 207 self.generate_cartesian_product(context, variable_names, index + 1, current_combination, combinations); 208 } 209 }, 210 VariableBinding::Relationships(rel_ids) => { 211 for &rel_id in rel_ids { 212 current_combination.insert(var_name.clone(), VariableBinding::Relationships(vec![rel_id])); 213 self.generate_cartesian_product(context, variable_names, index + 1, current_combination, combinations); 214 } 215 } 216 } 217 } 218 } 219 220 fn rebuild_context_from_combinations(&self, context: &mut ExecutionContext, combinations: Vec<HashMap<String, VariableBinding>>) { 221 // Clear current context 222 context.variables.clear(); 223 224 // Group combinations back into variable bindings 225 let mut var_to_nodes: HashMap<String, Vec<NodeId>> = HashMap::new(); 226 let mut var_to_rels: HashMap<String, Vec<RelationshipId>> = HashMap::new(); 227 228 for combination in combinations { 229 for (var_name, binding) in combination { 230 match binding { 231 VariableBinding::Nodes(node_ids) => { 232 var_to_nodes.entry(var_name).or_insert_with(Vec::new).extend(node_ids); 233 }, 234 VariableBinding::Relationships(rel_ids) => { 235 var_to_rels.entry(var_name).or_insert_with(Vec::new).extend(rel_ids); 236 } 237 } 238 } 239 } 240 241 // Rebuild context with filtered bindings 242 for (var_name, node_ids) in var_to_nodes { 243 context.bind_variable(var_name, VariableBinding::Nodes(node_ids)); 244 } 245 246 for (var_name, rel_ids) in var_to_rels { 247 context.bind_variable(var_name, VariableBinding::Relationships(rel_ids)); 248 } 249 } 250 251 async fn find_matching_nodes(&self, node_pattern: &crate::cypher::ast::NodePattern) -> Result<Vec<NodeId>> { 252 debug!("Finding nodes matching pattern: labels={:?}, properties={:?}", 253 node_pattern.labels, node_pattern.properties); 254 255 let mut candidate_nodes: Option<Vec<NodeId>> = None; 256 257 // Use label indexes if labels are specified 258 if !node_pattern.labels.is_empty() { 259 debug!("Using label indexes for labels: {:?}", node_pattern.labels); 260 let mut label_matches = Vec::new(); 261 262 for label_name in &node_pattern.labels { 263 match self.graph.find_nodes_by_label(label_name) { 264 Ok(nodes) => { 265 if label_matches.is_empty() { 266 label_matches = nodes; 267 } else { 268 // Intersect with previous results (AND logic for multiple labels) 269 label_matches.retain(|node_id| nodes.contains(node_id)); 270 } 271 }, 272 Err(e) => { 273 debug!("Failed to use label index for '{}': {}", label_name, e); 274 // Fall back to scanning all nodes 275 label_matches = self.graph.get_all_nodes(); 276 break; 277 } 278 } 279 } 280 281 candidate_nodes = Some(label_matches); 282 info!("Label index returned {} candidate nodes", candidate_nodes.as_ref().unwrap().len()); 283 } 284 285 // Use property indexes if properties are specified 286 if let Some(ref properties) = node_pattern.properties { 287 debug!("Using property indexes for {} properties", properties.len()); 288 let mut property_matches: Option<Vec<NodeId>> = None; 289 290 for (prop_name, value_expr) in properties { 291 // For now, only handle literal values in property patterns 292 if let Expression::Literal(prop_value) = value_expr { 293 match self.graph.find_nodes_by_property(prop_name, prop_value) { 294 Ok(nodes) => { 295 if let Some(ref mut existing_matches) = property_matches { 296 // Intersect with previous property matches 297 existing_matches.retain(|node_id| nodes.contains(node_id)); 298 } else { 299 property_matches = Some(nodes); 300 } 301 }, 302 Err(e) => { 303 debug!("Failed to use property index for '{}': {}", prop_name, e); 304 // Continue with other properties or fall back to scanning 305 } 306 } 307 } 308 } 309 310 if let Some(prop_nodes) = property_matches { 311 if let Some(ref mut candidates) = candidate_nodes { 312 // Intersect label matches with property matches 313 candidates.retain(|node_id| prop_nodes.contains(node_id)); 314 } else { 315 candidate_nodes = Some(prop_nodes); 316 } 317 info!("Property index intersection returned {} candidate nodes", 318 candidate_nodes.as_ref().unwrap().len()); 319 } 320 } 321 322 // If no indexes were used, scan all nodes 323 let result_nodes = candidate_nodes.unwrap_or_else(|| { 324 debug!("No indexes available, scanning all nodes"); 325 self.graph.get_all_nodes() 326 }); 327 328 // TODO: Apply additional filtering for complex property expressions 329 // that couldn't be handled by indexes 330 331 debug!("Final result: {} nodes matched the pattern", result_nodes.len()); 332 Ok(result_nodes) 333 } 334 335 async fn get_all_relationships(&self) -> Result<Vec<RelationshipId>> { 336 // Get all relationships in the graph 337 // This is a simplified implementation - normally we'd iterate through the graph structure 338 let mut all_relationships = Vec::new(); 339 340 // For each node, get its relationships 341 for node_id in self.graph.get_all_nodes() { 342 let relationships = self.graph.get_node_relationships( 343 node_id, 344 crate::core::relationship::Direction::Both, 345 None 346 ); 347 348 for rel in relationships { 349 if !all_relationships.contains(&rel.id) { 350 all_relationships.push(rel.id); 351 } 352 } 353 } 354 355 Ok(all_relationships) 356 } 357 358 async fn execute_create_query(&self, create_clause: &CreateClause) -> Result<QueryResult> { 359 // Create new nodes/relationships based on pattern 360 let mut created_nodes = Vec::new(); 361 let mut created_relationships = Vec::new(); 362 let mut node_variables = HashMap::new(); 363 364 // First pass: create all nodes 365 for element in &create_clause.pattern.elements { 366 if let PatternElement::Node(node_pattern) = element { 367 // Create a new node 368 let node_id = self.graph.create_node(); 369 370 // Add labels and properties using update_node 371 self.graph.update_node(node_id, |node| { 372 // Add labels if specified 373 if !node_pattern.labels.is_empty() { 374 let schema = self.graph.schema(); 375 for label_name in &node_pattern.labels { 376 let label_id = { 377 let mut schema_guard = schema.write(); 378 schema_guard.get_or_create_label(label_name) 379 }; 380 node.add_label(label_id); 381 } 382 } 383 384 // Add properties if specified 385 if let Some(ref properties) = node_pattern.properties { 386 let schema = self.graph.schema(); 387 for (key, value_expr) in properties { 388 let property_key_id = { 389 let mut schema_guard = schema.write(); 390 schema_guard.get_or_create_property_key(key) 391 }; 392 393 // Convert expression to property value (simplified) 394 let property_value = match value_expr { 395 Expression::Literal(literal) => literal.clone(), 396 _ => PropertyValue::String("unknown".to_string()), 397 }; 398 399 node.properties.insert(property_key_id, property_value); 400 } 401 } 402 })?; 403 404 created_nodes.push(node_id); 405 406 // Add to indexes after creating the node 407 if let Some(node) = self.graph.get_node(node_id) { 408 let labels: Vec<_> = node.labels.iter().cloned().collect(); 409 let properties = node.properties.clone(); 410 411 // Ensure indexes exist for any new labels 412 for &label_id in &labels { 413 let index_type = IndexType::Label(label_id); 414 if let Err(e) = self.graph.index_manager().create_index(index_type, None, false) { 415 debug!("Label index may already exist or failed to create: {}", e); 416 } 417 } 418 419 // Ensure indexes exist for any new properties 420 for &property_key_id in properties.keys() { 421 let index_type = IndexType::Property(property_key_id); 422 if let Err(e) = self.graph.index_manager().create_index(index_type, None, false) { 423 debug!("Property index may already exist or failed to create: {}", e); 424 } 425 } 426 427 // Add node to indexes 428 if let Err(e) = self.graph.index_manager().add_node(node_id, &labels, &properties) { 429 debug!("Failed to add created node to indexes: {}", e); 430 } else { 431 debug!("Added newly created node {} to indexes", node_id.0); 432 } 433 } 434 435 // Store node variable mapping for relationships 436 if let Some(var_name) = &node_pattern.variable { 437 node_variables.insert(var_name.clone(), node_id); 438 } 439 } 440 } 441 442 // Second pass: create relationships between nodes 443 let mut i = 0; 444 while i < create_clause.pattern.elements.len() { 445 if i + 2 < create_clause.pattern.elements.len() { 446 if let (PatternElement::Node(start_node), PatternElement::Relationship(rel_pattern), PatternElement::Node(end_node)) = 447 (&create_clause.pattern.elements[i], &create_clause.pattern.elements[i + 1], &create_clause.pattern.elements[i + 2]) { 448 449 // Get start and end node IDs 450 let start_id = if let Some(var_name) = &start_node.variable { 451 node_variables.get(var_name).copied() 452 } else { 453 created_nodes.first().copied() 454 }; 455 456 let end_id = if let Some(var_name) = &end_node.variable { 457 node_variables.get(var_name).copied() 458 } else { 459 created_nodes.last().copied() 460 }; 461 462 if let (Some(start_id), Some(end_id)) = (start_id, end_id) { 463 // Create the relationship 464 let rel_type_id = if let Some(rel_type_name) = rel_pattern.types.first() { 465 let schema = self.graph.schema(); 466 let mut schema_guard = schema.write(); 467 schema_guard.get_or_create_relationship_type(rel_type_name) 468 } else { 469 0 // Default relationship type 470 }; 471 472 let rel_id = self.graph.create_relationship(start_id, end_id, rel_type_id)?; 473 created_relationships.push(rel_id); 474 475 // Add relationship properties if specified 476 if let Some(ref properties) = rel_pattern.properties { 477 // TODO: Implement relationship property setting 478 // This would require extending the graph API to update relationship properties 479 } 480 } 481 482 i += 3; // Skip the relationship pattern and end node 483 } else { 484 i += 1; 485 } 486 } else { 487 i += 1; 488 } 489 } 490 491 // Return result indicating what was created 492 let mut columns = Vec::new(); 493 let mut values = Vec::new(); 494 495 if !created_nodes.is_empty() { 496 columns.push("nodes_created".to_string()); 497 values.push(Value::Integer(created_nodes.len() as i64)); 498 } 499 500 if !created_relationships.is_empty() { 501 columns.push("relationships_created".to_string()); 502 values.push(Value::Integer(created_relationships.len() as i64)); 503 } 504 505 let rows = if !values.is_empty() { 506 vec![Row { values }] 507 } else { 508 vec![Row { values: vec![Value::Integer(0)] }] 509 }; 510 511 Ok(QueryResult { rows, columns }) 512 } 513 514 async fn execute_return(&self, return_clause: &ReturnClause) -> Result<QueryResult> { 515 let mut context = ExecutionContext::new(); 516 self.execute_return_with_context(return_clause, &mut context).await 517 } 518 519 async fn execute_return_with_context(&self, return_clause: &ReturnClause, context: &ExecutionContext) -> Result<QueryResult> { 520 let mut columns = Vec::new(); 521 let mut rows = Vec::new(); 522 523 // Extract column names 524 for item in &return_clause.items { 525 let column_name = if let Some(alias) = &item.alias { 526 alias.clone() 527 } else { 528 self.expression_to_string(&item.expression) 529 }; 530 columns.push(column_name); 531 } 532 533 // Generate result rows based on variable bindings 534 if let Some(first_binding) = context.variables.values().next() { 535 match first_binding { 536 VariableBinding::Nodes(node_ids) => { 537 for node_id in node_ids { 538 let mut values = Vec::new(); 539 for item in &return_clause.items { 540 values.push(self.evaluate_expression(&item.expression, context, Some(*node_id)).await?); 541 } 542 rows.push(Row { values }); 543 } 544 }, 545 _ => {} 546 } 547 } 548 549 Ok(QueryResult { rows, columns }) 550 } 551 552 fn evaluate_expression<'a>(&'a self, expr: &'a Expression, context: &'a ExecutionContext, current_node: Option<NodeId>) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Value>> + 'a>> { 553 Box::pin(async move { 554 match expr { 555 Expression::Variable(var_name) => { 556 if let Some(binding) = context.variables.get(var_name) { 557 match binding { 558 VariableBinding::Nodes(nodes) => { 559 if let Some(node_id) = current_node { 560 Ok(Value::Node(node_id)) 561 } else if let Some(&first_node) = nodes.first() { 562 Ok(Value::Node(first_node)) 563 } else { 564 Ok(Value::Null) 565 } 566 }, 567 VariableBinding::Relationships(rels) => { 568 if let Some(&first_rel) = rels.first() { 569 Ok(Value::Relationship(first_rel)) 570 } else { 571 Ok(Value::Null) 572 } 573 } 574 } 575 } else { 576 Ok(Value::Null) 577 } 578 }, 579 Expression::Property(prop_expr) => { 580 let base_value = self.evaluate_expression(&prop_expr.expression, context, current_node).await?; 581 self.get_property_value(base_value, &prop_expr.property).await 582 }, 583 Expression::Literal(literal) => { 584 Ok(self.property_value_to_executor_value(literal)) 585 }, 586 Expression::Equal(left, right) => { 587 let left_val = self.evaluate_expression(left, context, current_node).await?; 588 let right_val = self.evaluate_expression(right, context, current_node).await?; 589 Ok(Value::Boolean(self.values_equal(&left_val, &right_val))) 590 }, 591 Expression::NotEqual(left, right) => { 592 let left_val = self.evaluate_expression(left, context, current_node).await?; 593 let right_val = self.evaluate_expression(right, context, current_node).await?; 594 Ok(Value::Boolean(!self.values_equal(&left_val, &right_val))) 595 }, 596 Expression::And(left, right) => { 597 let left_val = self.evaluate_expression(left, context, current_node).await?; 598 let right_val = self.evaluate_expression(right, context, current_node).await?; 599 Ok(Value::Boolean(self.is_truthy(&left_val) && self.is_truthy(&right_val))) 600 }, 601 Expression::Or(left, right) => { 602 let left_val = self.evaluate_expression(left, context, current_node).await?; 603 let right_val = self.evaluate_expression(right, context, current_node).await?; 604 Ok(Value::Boolean(self.is_truthy(&left_val) || self.is_truthy(&right_val))) 605 }, 606 Expression::Not(expr) => { 607 let val = self.evaluate_expression(expr, context, current_node).await?; 608 Ok(Value::Boolean(!self.is_truthy(&val))) 609 }, 610 Expression::LessThan(left, right) => { 611 let left_val = self.evaluate_expression(left, context, current_node).await?; 612 let right_val = self.evaluate_expression(right, context, current_node).await?; 613 Ok(Value::Boolean(self.compare_values(&left_val, &right_val) < 0)) 614 }, 615 Expression::LessThanOrEqual(left, right) => { 616 let left_val = self.evaluate_expression(left, context, current_node).await?; 617 let right_val = self.evaluate_expression(right, context, current_node).await?; 618 Ok(Value::Boolean(self.compare_values(&left_val, &right_val) <= 0)) 619 }, 620 Expression::GreaterThan(left, right) => { 621 let left_val = self.evaluate_expression(left, context, current_node).await?; 622 let right_val = self.evaluate_expression(right, context, current_node).await?; 623 Ok(Value::Boolean(self.compare_values(&left_val, &right_val) > 0)) 624 }, 625 Expression::GreaterThanOrEqual(left, right) => { 626 let left_val = self.evaluate_expression(left, context, current_node).await?; 627 let right_val = self.evaluate_expression(right, context, current_node).await?; 628 Ok(Value::Boolean(self.compare_values(&left_val, &right_val) >= 0)) 629 }, 630 _ => Ok(Value::Null), // TODO: Implement remaining expression types 631 } 632 }) 633 } 634 635 async fn get_property_value(&self, base_value: Value, property_name: &str) -> Result<Value> { 636 match base_value { 637 Value::Node(node_id) => { 638 if let Some(node) = self.graph.get_node(node_id) { 639 // Get property value from node 640 let schema = self.graph.schema(); 641 let schema_guard = schema.read(); 642 for (prop_key, _) in &schema_guard.property_keys { 643 if prop_key == property_name { 644 let prop_key_id = schema_guard.property_keys[prop_key]; 645 if let Some(prop_value) = node.properties.get(&prop_key_id) { 646 return Ok(self.property_value_to_executor_value(prop_value)); 647 } 648 } 649 } 650 } 651 Ok(Value::Null) 652 }, 653 Value::Relationship(_rel_id) => { 654 // TODO: Implement relationship property access 655 Ok(Value::Null) 656 }, 657 _ => Ok(Value::Null), 658 } 659 } 660 661 fn property_value_to_executor_value(&self, prop_val: &PropertyValue) -> Value { 662 match prop_val { 663 PropertyValue::String(s) => Value::String(s.clone()), 664 PropertyValue::Integer(i) => Value::Integer(*i), 665 PropertyValue::Float(f) => Value::Float(*f), 666 PropertyValue::Boolean(b) => Value::Boolean(*b), 667 PropertyValue::List(list) => { 668 let converted_list: Vec<Value> = list.iter() 669 .map(|item| self.property_value_to_executor_value(item)) 670 .collect(); 671 Value::List(converted_list) 672 }, 673 PropertyValue::Null => Value::Null, 674 PropertyValue::Map(_) => Value::Null, // TODO: Implement map support 675 } 676 } 677 678 fn values_equal(&self, left: &Value, right: &Value) -> bool { 679 match (left, right) { 680 (Value::String(a), Value::String(b)) => a == b, 681 (Value::Integer(a), Value::Integer(b)) => a == b, 682 (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON, 683 (Value::Boolean(a), Value::Boolean(b)) => a == b, 684 (Value::Node(a), Value::Node(b)) => a == b, 685 (Value::Relationship(a), Value::Relationship(b)) => a == b, 686 (Value::Null, Value::Null) => true, 687 // Type coercion for numbers 688 (Value::Integer(a), Value::Float(b)) => (*a as f64 - b).abs() < f64::EPSILON, 689 (Value::Float(a), Value::Integer(b)) => (a - *b as f64).abs() < f64::EPSILON, 690 _ => false, 691 } 692 } 693 694 fn is_truthy(&self, value: &Value) -> bool { 695 match value { 696 Value::Boolean(b) => *b, 697 Value::Null => false, 698 Value::Integer(i) => *i != 0, 699 Value::Float(f) => *f != 0.0, 700 Value::String(s) => !s.is_empty(), 701 Value::List(list) => !list.is_empty(), 702 Value::Node(_) => true, 703 Value::Relationship(_) => true, 704 } 705 } 706 707 fn compare_values(&self, left: &Value, right: &Value) -> i32 { 708 match (left, right) { 709 (Value::Integer(a), Value::Integer(b)) => a.cmp(b) as i32, 710 (Value::Float(a), Value::Float(b)) => a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal) as i32, 711 (Value::Integer(a), Value::Float(b)) => (*a as f64).partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal) as i32, 712 (Value::Float(a), Value::Integer(b)) => a.partial_cmp(&(*b as f64)).unwrap_or(std::cmp::Ordering::Equal) as i32, 713 (Value::String(a), Value::String(b)) => a.cmp(b) as i32, 714 _ => 0, // Incomparable types are considered equal 715 } 716 } 717 718 fn expression_to_string(&self, expr: &Expression) -> String { 719 match expr { 720 Expression::Variable(name) => name.clone(), 721 _ => "expr".to_string(), 722 } 723 } 724 725 pub async fn execute(&self, plan: QueryPlan) -> Result<QueryResult> { 726 match plan { 727 QueryPlan::Scan(scan_plan) => self.execute_scan(scan_plan).await, 728 QueryPlan::Create(create_plan) => self.execute_create(create_plan).await, 729 QueryPlan::Project(project_plan) => self.execute_project(project_plan).await, 730 _ => Err(GigabrainError::Query("Execution not implemented for this plan type".to_string())), 731 } 732 } 733 734 async fn execute_scan(&self, _scan_plan: ScanPlan) -> Result<QueryResult> { 735 Ok(QueryResult::empty()) 736 } 737 738 async fn execute_create(&self, _create_plan: CreatePlan) -> Result<QueryResult> { 739 Ok(QueryResult::empty()) 740 } 741 742 async fn execute_project(&self, _project_plan: ProjectPlan) -> Result<QueryResult> { 743 Ok(QueryResult::empty()) 744 } 745} 746 747#[derive(Debug)] 748pub struct ExecutionContext { 749 variables: HashMap<String, VariableBinding>, 750} 751 752impl ExecutionContext { 753 fn new() -> Self { 754 Self { 755 variables: HashMap::new(), 756 } 757 } 758 759 fn bind_variable(&mut self, name: String, binding: VariableBinding) { 760 self.variables.insert(name, binding); 761 } 762 763 fn merge_result(&mut self, _result: QueryResult) { 764 // Merge results from previous query steps 765 } 766 767 fn into_result(self) -> QueryResult { 768 // If we have variable bindings, create a result from them 769 if let Some((var_name, binding)) = self.variables.iter().next() { 770 match binding { 771 VariableBinding::Nodes(node_ids) => { 772 let columns = vec![var_name.clone()]; 773 let mut rows = Vec::new(); 774 for node_id in node_ids { 775 rows.push(Row { 776 values: vec![Value::Node(*node_id)] 777 }); 778 } 779 QueryResult { rows, columns } 780 }, 781 VariableBinding::Relationships(rel_ids) => { 782 let columns = vec![var_name.clone()]; 783 let mut rows = Vec::new(); 784 for rel_id in rel_ids { 785 rows.push(Row { 786 values: vec![Value::Relationship(*rel_id)] 787 }); 788 } 789 QueryResult { rows, columns } 790 }, 791 } 792 } else { 793 QueryResult::empty() 794 } 795 } 796} 797 798#[derive(Debug, Clone)] 799enum VariableBinding { 800 Nodes(Vec<NodeId>), 801 Relationships(Vec<RelationshipId>), 802} 803 804#[derive(Debug)] 805pub struct QueryResult { 806 pub rows: Vec<Row>, 807 pub columns: Vec<String>, 808} 809 810impl QueryResult { 811 fn empty() -> Self { 812 Self { 813 rows: Vec::new(), 814 columns: Vec::new(), 815 } 816 } 817} 818 819#[derive(Debug)] 820pub struct Row { 821 pub values: Vec<Value>, 822} 823 824#[derive(Debug)] 825pub enum Value { 826 Null, 827 Node(crate::NodeId), 828 Relationship(crate::RelationshipId), 829 Integer(i64), 830 Float(f64), 831 String(String), 832 Boolean(bool), 833 List(Vec<Value>), 834}