1919
2020use crate :: cast:: can_cast_types;
2121use crate :: cast_with_options;
22- use arrow_array:: { Array , ArrayRef , UnionArray , new_null_array } ;
22+ use arrow_array:: { Array , ArrayRef , UnionArray } ;
2323use arrow_schema:: { ArrowError , DataType , FieldRef , UnionFields } ;
2424use arrow_select:: union_extract:: union_extract;
2525
@@ -126,7 +126,15 @@ pub fn union_extract_by_type(
126126 } ;
127127
128128 let Some ( field) = resolve_variant ( fields, target_type) else {
129- return Ok ( new_null_array ( target_type, union_array. len ( ) ) ) ;
129+ return Err ( ArrowError :: CastError ( format ! (
130+ "cannot cast Union with fields {} to {}" ,
131+ fields
132+ . iter( )
133+ . map( |( _, f) | f. data_type( ) . to_string( ) )
134+ . collect:: <Vec <_>>( )
135+ . join( ", " ) ,
136+ target_type
137+ ) ) ) ;
130138 } ;
131139
132140 let extracted = union_extract ( union_array, field. name ( ) ) ?;
@@ -337,10 +345,9 @@ mod tests {
337345
338346 // no matching variant — all three passes fail.
339347 // Union(Int32, Utf8) targeting Struct({x: Int32}). neither Int32 nor Utf8
340- // can be cast to a Struct, so can_cast_types returns false and
341- // union_extract_by_type returns an all-null array.
348+ // can be cast to a Struct, so both can_cast_types and cast return errors.
342349 #[ test]
343- fn test_no_match_returns_nulls ( ) {
350+ fn test_no_match_errors ( ) {
344351 let target = DataType :: Struct ( vec ! [ Field :: new( "x" , DataType :: Int32 , true ) ] . into ( ) ) ;
345352
346353 assert ! ( !can_cast_types(
@@ -359,9 +366,7 @@ mod tests {
359366 )
360367 . unwrap ( ) ;
361368
362- let result = union_extract_by_type ( & union, & target, & CastOptions :: default ( ) ) . unwrap ( ) ;
363- assert_eq ! ( result. data_type( ) , & target) ;
364- assert_eq ! ( result. null_count( ) , 2 ) ;
369+ assert ! ( cast:: cast( & union , & target) . is_err( ) ) ;
365370 }
366371
367372 // priority: exact match (pass 1) wins over family match (pass 2).
0 commit comments