| 294 | |
| 295 | impl PhysicalExpr for HigherOrderFunctionExpr { |
| 296 | fn evaluate(&self, batch: &RecordBatch) -> Result<ColumnarValue> { |
| 297 | let mut arg_fields = Vec::with_capacity(self.args.len()); |
| 298 | let mut fields = Vec::with_capacity(self.args.len()); |
| 299 | for (arg, slot) in self.args.iter().zip(&self.slots) { |
| 300 | match slot { |
| 301 | ArgSlot::Lambda(lambda) => { |
| 302 | let field = lambda.body().return_field(batch.schema_ref())?; |
| 303 | arg_fields.push(ValueOrLambda::Lambda(Arc::clone(&field))); |
| 304 | fields.push(ValueOrLambda::Lambda(Some(field))); |
| 305 | } |
| 306 | ArgSlot::Value => { |
| 307 | let field = arg.return_field(batch.schema_ref())?; |
| 308 | arg_fields.push(ValueOrLambda::Value(Arc::clone(&field))); |
| 309 | fields.push(ValueOrLambda::Value(field)); |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | let mut lambda_parameters = self.resolve_lambda_parameters(&fields)?.into_iter(); |
| 315 | |
| 316 | let args = self |
| 317 | .args |
| 318 | .iter() |
| 319 | .zip(&self.slots) |
| 320 | .map(|(arg, slot)| match slot { |
| 321 | ArgSlot::Lambda(lambda) => { |
| 322 | let lambda_params = lambda_parameters.next().ok_or_else(|| { |
| 323 | internal_datafusion_err!( |
| 324 | "params len should have been checked above" |
| 325 | ) |
| 326 | })?; |
| 327 | |
| 328 | if lambda.params().len() > lambda_params.len() { |
| 329 | return exec_err!( |
| 330 | "lambda defined {} params but higher-order function support only {}", |
| 331 | lambda.params().len(), |
| 332 | lambda_params.len() |
| 333 | ); |
| 334 | } |
| 335 | |
| 336 | let params = std::iter::zip(lambda.params(), lambda_params) |
| 337 | .map(|(name, param)| param.renamed(name.as_str())) |
| 338 | .collect(); |
| 339 | |
| 340 | // lambda.projection may include indexes of nested lambda variables not present on this batch |
| 341 | let projection = lambda |
| 342 | .projection() |
| 343 | .iter() |
| 344 | .copied() |
| 345 | .filter(|i| *i < batch.num_columns()) |
| 346 | .collect::<Vec<_>>(); |
| 347 | |
| 348 | Ok(ValueOrLambda::Lambda(LambdaArgument::new( |
| 349 | params, |
| 350 | Arc::clone(lambda.projected_body()), |
| 351 | if projection.is_empty() { |
| 352 | None |
| 353 | } else { |