MCPcopy Create free account
hub / github.com/apache/datafusion / cast_struct_column

Function cast_struct_column

datafusion/common/src/nested_struct.rs:56–115  ·  view source on GitHub ↗

Cast a struct column to match target struct fields, handling nested structs recursively. This function implements struct-to-struct casting with the assumption that **structs should always be allowed to cast to other structs**. However, the source column must already be a struct type - non-struct sources will result in an error. ## Field Matching Strategy - **By Name**: Source struct fields are m

(
    source_col: &ArrayRef,
    target_fields: &[Arc<Field>],
    cast_options: &CastOptions,
)

Source from the content-addressed store, hash-verified

54/// # Errors
55/// Returns a `DataFusionError::Plan` if the source column is not a struct type
56fn cast_struct_column(
57 source_col: &ArrayRef,
58 target_fields: &[Arc<Field>],
59 cast_options: &CastOptions,
60) -> Result<ArrayRef> {
61 if source_col.data_type() == &DataType::Null
62 || (!source_col.is_empty() && source_col.null_count() == source_col.len())
63 {
64 return Ok(new_null_array(
65 &Struct(target_fields.to_vec().into()),
66 source_col.len(),
67 ));
68 }
69
70 if let Some(source_struct) = source_col.as_any().downcast_ref::<StructArray>() {
71 let source_fields = source_struct.fields();
72 validate_struct_compatibility(source_fields, target_fields)?;
73 let mut fields: Vec<Arc<Field>> = Vec::with_capacity(target_fields.len());
74 let mut arrays: Vec<ArrayRef> = Vec::with_capacity(target_fields.len());
75 let num_rows = source_col.len();
76
77 // Iterate target fields and pick source child by name when present.
78 for target_child_field in target_fields.iter() {
79 fields.push(Arc::clone(target_child_field));
80
81 let source_child_opt =
82 source_struct.column_by_name(target_child_field.name());
83
84 match source_child_opt {
85 Some(source_child_col) => {
86 let adapted_child = cast_column(
87 source_child_col,
88 target_child_field.data_type(),
89 cast_options,
90 )
91 .map_err(|e| {
92 e.context(format!(
93 "While casting struct field '{}'",
94 target_child_field.name()
95 ))
96 })?;
97 arrays.push(adapted_child);
98 }
99 None => {
100 arrays.push(new_null_array(target_child_field.data_type(), num_rows));
101 }
102 }
103 }
104
105 let struct_array =
106 StructArray::new(fields.into(), arrays, source_struct.nulls().cloned());
107 Ok(Arc::new(struct_array))
108 } else {
109 // Return error if source is not a struct type
110 _plan_err!(
111 "Cannot cast column of type {} to struct type. Source must be a struct to cast to struct.",
112 source_col.data_type()
113 )

Callers 1

cast_columnFunction · 0.85

Calls 15

cast_columnFunction · 0.85
newFunction · 0.85
null_countMethod · 0.80
to_vecMethod · 0.80
contextMethod · 0.80
StructClass · 0.50
data_typeMethod · 0.45
is_emptyMethod · 0.45
lenMethod · 0.45
intoMethod · 0.45
as_anyMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…