Returns a [arrow::datatypes::Field] compatible with this expression. This function converts an expression into a field with appropriate metadata and nullability based on the expression type and context. It is the primary mechanism for determining field-level schemas. # Field Property Resolution For each expression, the following properties are determined: ## Data Type Resolution - **Column ref
(
&self,
schema: &dyn ExprSchema,
)
| 472 | /// [`return_field_from_args`]: crate::ScalarUDF::return_field_from_args |
| 473 | /// [`return_field`]: crate::AggregateUDF::return_field |
| 474 | fn to_field( |
| 475 | &self, |
| 476 | schema: &dyn ExprSchema, |
| 477 | ) -> Result<(Option<TableReference>, Arc<Field>)> { |
| 478 | let (relation, schema_name) = self.qualified_name(); |
| 479 | #[expect(deprecated)] |
| 480 | let field = match self { |
| 481 | Expr::Alias(Alias { |
| 482 | expr, |
| 483 | name: _, |
| 484 | metadata, |
| 485 | .. |
| 486 | }) => { |
| 487 | let mut combined_metadata = expr.metadata(schema)?; |
| 488 | if let Some(metadata) = metadata { |
| 489 | combined_metadata.extend(metadata.clone()); |
| 490 | } |
| 491 | |
| 492 | Ok(expr |
| 493 | .to_field(schema) |
| 494 | .map(|(_, f)| f)? |
| 495 | .with_field_metadata(&combined_metadata)) |
| 496 | } |
| 497 | Expr::Negative(expr) => expr.to_field(schema).map(|(_, f)| f), |
| 498 | Expr::Column(c) => schema.field_from_column(c).map(Arc::clone), |
| 499 | Expr::OuterReferenceColumn(field, _) => { |
| 500 | Ok(Arc::clone(field).renamed(&schema_name)) |
| 501 | } |
| 502 | Expr::ScalarVariable(field, _) => Ok(Arc::clone(field).renamed(&schema_name)), |
| 503 | Expr::Literal(l, metadata) => Ok(Arc::new( |
| 504 | Field::new(&schema_name, l.data_type(), l.is_null()) |
| 505 | .with_field_metadata_opt(metadata.as_ref()), |
| 506 | )), |
| 507 | Expr::IsNull(_) |
| 508 | | Expr::IsNotNull(_) |
| 509 | | Expr::IsTrue(_) |
| 510 | | Expr::IsFalse(_) |
| 511 | | Expr::IsUnknown(_) |
| 512 | | Expr::IsNotTrue(_) |
| 513 | | Expr::IsNotFalse(_) |
| 514 | | Expr::IsNotUnknown(_) |
| 515 | | Expr::Exists { .. } => { |
| 516 | Ok(Arc::new(Field::new(&schema_name, DataType::Boolean, false))) |
| 517 | } |
| 518 | Expr::ScalarSubquery(subquery) => { |
| 519 | Ok(Arc::clone(&subquery.subquery.schema().fields()[0])) |
| 520 | } |
| 521 | Expr::BinaryExpr(BinaryExpr { left, right, op }) => { |
| 522 | let (left_field, right_field) = |
| 523 | (left.to_field(schema)?.1, right.to_field(schema)?.1); |
| 524 | |
| 525 | let (lhs_type, lhs_nullable) = |
| 526 | (left_field.data_type(), left_field.is_nullable()); |
| 527 | let (rhs_type, rhs_nullable) = |
| 528 | (right_field.data_type(), right_field.is_nullable()); |
| 529 | let mut coercer = BinaryTypeCoercer::new(lhs_type, op, rhs_type); |
| 530 | coercer.set_lhs_spans(left.spans().cloned().unwrap_or_default()); |
| 531 | coercer.set_rhs_spans(right.spans().cloned().unwrap_or_default()); |