MCPcopy Create free account
hub / github.com/GraphLite-AI/GraphLite / execute_aggregate_projection

Method execute_aggregate_projection

graphlite/src/exec/executor.rs:6056–6122  ·  view source on GitHub ↗

Execute projection with aggregate functions (returns single row)

(
        &self,
        expressions: &[ProjectionItem],
        input_rows: Vec<Row>,
        context: &mut ExecutionContext,
    )

Source from the content-addressed store, hash-verified

6054
6055 /// Execute projection with aggregate functions (returns single row)
6056 fn execute_aggregate_projection(
6057 &self,
6058 expressions: &[ProjectionItem],
6059 input_rows: Vec<Row>,
6060 context: &mut ExecutionContext,
6061 ) -> Result<Vec<Row>, ExecutionError> {
6062 let mut result_row = Row::new();
6063
6064 // Evaluate each projection expression with all input rows
6065 for proj_item in expressions {
6066 let value = if let Expression::FunctionCall(func_call) = &proj_item.expression {
6067 // Handle aggregate function
6068 let function = self.function_registry.get(&func_call.name).ok_or_else(|| {
6069 ExecutionError::UnsupportedOperator(format!(
6070 "Function not found: {}",
6071 func_call.name
6072 ))
6073 })?;
6074
6075 // Evaluate arguments (currently COUNT has no arguments, but others might)
6076 let mut evaluated_args = Vec::new();
6077 for arg in &func_call.arguments {
6078 // For arguments like AVERAGE(account.balance), we need to pass the full property path
6079 if let Expression::PropertyAccess(prop) = arg {
6080 // Pass the full property path (e.g., "account.balance", "account.id")
6081 let full_property = format!("{}.{}", prop.object, prop.property);
6082 evaluated_args.push(Value::String(full_property));
6083 } else if let Expression::Variable(var) = arg {
6084 evaluated_args.push(Value::String(var.name.clone()));
6085 } else {
6086 // For other expression types, evaluate them using the existing context
6087 let value = self.evaluate_expression(arg, context)?;
6088 evaluated_args.push(value);
6089 }
6090 }
6091
6092 // Create function context with all input rows and storage access
6093 let function_context = FunctionContext::with_storage(
6094 input_rows.clone(),
6095 HashMap::new(),
6096 evaluated_args,
6097 context.storage_manager.clone(),
6098 context.current_graph.clone(),
6099 context.get_current_graph_name(),
6100 );
6101
6102 // Execute the function
6103 function.execute(&function_context).map_err(|e| {
6104 ExecutionError::UnsupportedOperator(format!("Function execution error: {}", e))
6105 })?
6106 } else {
6107 // Non-aggregate expression in aggregate context - this is usually invalid SQL
6108 // but for simplicity, we'll return null or error
6109 return Err(ExecutionError::ExpressionError(
6110 "Non-aggregate expressions not allowed with aggregate functions".to_string(),
6111 ));
6112 };
6113

Callers 1

execute_projectMethod · 0.80

Calls 7

cloneMethod · 0.80
expression_to_stringMethod · 0.80
getMethod · 0.45
evaluate_expressionMethod · 0.45
executeMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected