@@ -13,6 +13,7 @@ use arrow_array::GenericByteArray;
1313use arrow_array:: GenericByteViewArray ;
1414use arrow_array:: GenericListArray ;
1515use arrow_array:: GenericListViewArray ;
16+ use arrow_array:: MapArray as ArrowMapArray ;
1617use arrow_array:: NullArray as ArrowNullArray ;
1718use arrow_array:: OffsetSizeTrait ;
1819use arrow_array:: PrimitiveArray as ArrowPrimitiveArray ;
@@ -447,6 +448,20 @@ impl FromArrowArray<&ArrowFixedSizeListArray> for ArrayRef {
447448 }
448449}
449450
451+ impl FromArrowArray < & ArrowMapArray > for ArrayRef {
452+ fn from_arrow ( value : & ArrowMapArray , nullable : bool ) -> Self {
453+ // Arrow Map is logically List<Struct<key, value>> with i32 offsets.
454+ // We convert it to a ListArray of structs.
455+ let entries = Self :: from_arrow ( value. entries ( ) as & dyn ArrowArray , false ) ;
456+ let offsets = value. offsets ( ) . clone ( ) . into_array ( ) ;
457+ let nulls = nulls ( value. nulls ( ) , nullable) ;
458+
459+ ListArray :: try_new ( entries, offsets, nulls)
460+ . vortex_expect ( "Failed to convert Arrow MapArray to Vortex ListArray" )
461+ . into_array ( )
462+ }
463+ }
464+
450465impl FromArrowArray < & ArrowNullArray > for ArrayRef {
451466 fn from_arrow ( value : & ArrowNullArray , nullable : bool ) -> Self {
452467 assert ! ( nullable) ;
@@ -508,6 +523,7 @@ impl FromArrowArray<&dyn ArrowArray> for ArrayRef {
508523 DataType :: ListView ( _) => Self :: from_arrow ( array. as_list_view :: < i32 > ( ) , nullable) ,
509524 DataType :: LargeListView ( _) => Self :: from_arrow ( array. as_list_view :: < i64 > ( ) , nullable) ,
510525 DataType :: FixedSizeList ( ..) => Self :: from_arrow ( array. as_fixed_size_list ( ) , nullable) ,
526+ DataType :: Map ( ..) => Self :: from_arrow ( array. as_map ( ) , nullable) ,
511527 DataType :: Null => Self :: from_arrow ( as_null_array ( array) , nullable) ,
512528 DataType :: Timestamp ( u, _) => match u {
513529 ArrowTimeUnit :: Second => {
@@ -675,6 +691,7 @@ mod tests {
675691 use crate :: arrays:: VarBinVTable ;
676692 use crate :: arrays:: VarBinViewVTable ;
677693 use crate :: arrow:: FromArrowArray as _;
694+ use crate :: arrow:: executor:: ArrowArrayExecutor as _;
678695
679696 // Test primitive array conversions
680697 #[ test]
@@ -1757,4 +1774,54 @@ mod tests {
17571774
17581775 ArrayRef :: from_arrow ( null_struct_array_with_non_nullable_field. as_ref ( ) , true ) ;
17591776 }
1777+
1778+ #[ test]
1779+ fn test_map_array_conversion ( ) {
1780+ use arrow_array:: MapArray ;
1781+ use arrow_array:: builder:: MapBuilder ;
1782+ use arrow_array:: builder:: StringBuilder ;
1783+
1784+ // Build a MapArray: map<string, int32>
1785+ let mut builder = MapBuilder :: new ( None , StringBuilder :: new ( ) , Int32Builder :: new ( ) ) ;
1786+ // First map entry: {"a": 1, "b": 2}
1787+ builder. keys ( ) . append_value ( "a" ) ;
1788+ builder. values ( ) . append_value ( 1 ) ;
1789+ builder. keys ( ) . append_value ( "b" ) ;
1790+ builder. values ( ) . append_value ( 2 ) ;
1791+ builder. append ( true ) . unwrap ( ) ;
1792+
1793+ // Second map entry: null
1794+ builder. append ( false ) . unwrap ( ) ;
1795+
1796+ // Third map entry: {"c": 3}
1797+ builder. keys ( ) . append_value ( "c" ) ;
1798+ builder. values ( ) . append_value ( 3 ) ;
1799+ builder. append ( true ) . unwrap ( ) ;
1800+
1801+ let arrow_map = builder. finish ( ) ;
1802+ assert_eq ! ( arrow_map. len( ) , 3 ) ;
1803+
1804+ // Convert Arrow MapArray → Vortex ListArray
1805+ let vortex_array = ArrayRef :: from_arrow ( & arrow_map, true ) ;
1806+ assert_eq ! ( vortex_array. len( ) , 3 ) ;
1807+
1808+ // Verify it's stored as List<Struct<key, value>>
1809+ let list_array = vortex_array. as_ :: < ListVTable > ( ) ;
1810+ assert_eq ! ( list_array. elements( ) . len( ) , 3 ) ; // 3 total key-value pairs
1811+ let struct_elements = list_array. elements ( ) . as_ :: < StructVTable > ( ) ;
1812+ assert_eq ! ( struct_elements. names( ) . len( ) , 2 ) ; // key and value fields
1813+
1814+ // Convert back to Arrow as a MapArray
1815+ let map_dtype = arrow_map. data_type ( ) . clone ( ) ;
1816+ let arrow_back = vortex_array
1817+ . execute_arrow ( & map_dtype, & crate :: LEGACY_SESSION )
1818+ . unwrap ( ) ;
1819+ let map_back = arrow_back
1820+ . as_any ( )
1821+ . downcast_ref :: < MapArray > ( )
1822+ . expect ( "Should be a MapArray" ) ;
1823+ assert_eq ! ( map_back. len( ) , 3 ) ;
1824+ assert_eq ! ( map_back. entries( ) . len( ) , 3 ) ;
1825+ assert ! ( map_back. is_null( 1 ) ) ; // Second entry was null
1826+ }
17601827}
0 commit comments