friendlymatthew commented on code in PR #9544:
URL: https://github.com/apache/arrow-rs/pull/9544#discussion_r2926310435


##########
arrow-cast/src/cast/mod.rs:
##########
@@ -2276,6 +2305,108 @@ fn cast_struct_fields_in_order(
         .collect::<Result<Vec<ArrayRef>, ArrowError>>()
 }
 
+/// Cast a UnionArray to another UnionArray by casting each child array.
+fn cast_union_to_union(
+    array: &UnionArray,
+    from_fields: &UnionFields,
+    to_fields: &UnionFields,
+    _to_mode: UnionMode,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError> {
+    let type_ids = array.type_ids().clone();
+    let offsets = array.offsets().cloned();
+
+    let new_children: Vec<ArrayRef> = from_fields
+        .iter()
+        .map(|(from_id, _from_field)| {
+            let (_, to_field) = to_fields
+                .iter()
+                .find(|(to_id, _)| *to_id == from_id)
+                .ok_or_else(|| {
+                    ArrowError::CastError(format!(
+                        "Cannot cast union: type_id {from_id} not found in 
target union"
+                    ))
+                })?;
+            let child = array.child(from_id);
+            cast_with_options(child.as_ref(), to_field.data_type(), 
cast_options)
+        })
+        .collect::<Result<_, _>>()?;

Review Comment:
   look ups like this can go from n^2 to nlogn if we implement 
https://github.com/apache/arrow-rs/pull/8937, since sorting by `type_id` will 
give us `logn` searching



##########
arrow-cast/src/cast/mod.rs:
##########
@@ -1180,6 +1194,21 @@ pub fn cast_with_options(
         (_, Struct(_)) => Err(ArrowError::CastError(format!(
             "Casting from {from_type} to {to_type} not supported"
         ))),
+        (Union(from_fields, _), Union(to_fields, to_mode)) => 
cast_union_to_union(
+            array.as_any().downcast_ref::<UnionArray>().unwrap(),
+            from_fields,
+            to_fields,
+            *to_mode,
+            cast_options,
+        ),
+        (Union(_, _), _) => cast_union_to_type(
+            array.as_any().downcast_ref::<UnionArray>().unwrap(),
+            to_type,
+            cast_options,
+        ),
+        (_, Union(_, _)) => Err(ArrowError::CastError(format!(
+            "Casting from {from_type} to {to_type} not supported"
+        ))),

Review Comment:
   This PR does not support casting scalar types into a Union type
   
   It's not a feature that we currently need and will probably need more 
complex work to get it correct. Though, I think this is a cool/valid feature. I 
can file an issue if liked



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to