Execute WITH clause by routing through WithClauseProcessor (comprehensive consolidation approach)
(
&self,
with_clause: &WithClause,
input_rows: Vec<Row>,
context: &ExecutionContext,
)
| 1436 | |
| 1437 | /// Execute WITH clause by routing through WithClauseProcessor (comprehensive consolidation approach) |
| 1438 | fn execute_with_clause_via_processor( |
| 1439 | &self, |
| 1440 | with_clause: &WithClause, |
| 1441 | input_rows: Vec<Row>, |
| 1442 | context: &ExecutionContext, |
| 1443 | ) -> Result<Vec<Row>, ExecutionError> { |
| 1444 | // Create a context with the executor's function registry if not already present |
| 1445 | let enhanced_context = if context.function_registry.is_none() { |
| 1446 | // We need to copy the function registry from the executor, but since it's not Clone |
| 1447 | // we'll create a new context with a reference to a shared function registry |
| 1448 | let mut temp_context = context.clone(); |
| 1449 | temp_context.function_registry = Some(self.get_function_registry_arc()); |
| 1450 | temp_context |
| 1451 | } else { |
| 1452 | context.clone() |
| 1453 | }; |
| 1454 | // For WITH clauses that contain non-aggregation functions, |
| 1455 | // we need to evaluate them row by row before using the processor |
| 1456 | |
| 1457 | let has_non_aggregation_functions = with_clause.items.iter().any(|item| { |
| 1458 | if let Expression::FunctionCall(func_call) = &item.expression { |
| 1459 | !Self::is_with_aggregation_function(&func_call.name) |
| 1460 | } else { |
| 1461 | false |
| 1462 | } |
| 1463 | }); |
| 1464 | |
| 1465 | // Check if this is a simple variable pass-through (no functions at all) |
| 1466 | let is_simple_variable_passthrough = with_clause |
| 1467 | .items |
| 1468 | .iter() |
| 1469 | .all(|item| matches!(item.expression, Expression::Variable(_))); |
| 1470 | |
| 1471 | if is_simple_variable_passthrough && !input_rows.is_empty() { |
| 1472 | // Simple case: just pass through variables, preserving Node objects |
| 1473 | let mut result_rows = Vec::new(); |
| 1474 | |
| 1475 | for input_row in input_rows { |
| 1476 | let mut output_values = std::collections::HashMap::new(); |
| 1477 | |
| 1478 | for with_item in &with_clause.items { |
| 1479 | if let Expression::Variable(var) = &with_item.expression { |
| 1480 | let alias = if let Some(ref alias_name) = with_item.alias { |
| 1481 | alias_name.clone() |
| 1482 | } else { |
| 1483 | var.name.clone() |
| 1484 | }; |
| 1485 | |
| 1486 | if let Some(value) = input_row.values.get(&var.name) { |
| 1487 | output_values.insert(alias, value.clone()); |
| 1488 | } |
| 1489 | } |
| 1490 | } |
| 1491 | |
| 1492 | result_rows.push(Row::from_values(output_values)); |
| 1493 | } |
| 1494 | |
| 1495 | return Ok(result_rows); |
no test coverage detected