@@ -61,6 +61,7 @@ pub struct MapBuilder<K: ArrayBuilder, V: ArrayBuilder> {
6161 field_names : MapFieldNames ,
6262 key_builder : K ,
6363 value_builder : V ,
64+ key_field : Option < FieldRef > ,
6465 value_field : Option < FieldRef > ,
6566}
6667
@@ -107,13 +108,27 @@ impl<K: ArrayBuilder, V: ArrayBuilder> MapBuilder<K, V> {
107108 field_names : field_names. unwrap_or_default ( ) ,
108109 key_builder,
109110 value_builder,
111+ key_field : None ,
110112 value_field : None ,
111113 }
112114 }
113115
114116 /// Override the field passed to [`MapBuilder::new`]
115117 ///
116- /// By default a nullable field is created with the name `values`
118+ /// By default, a non-nullable field is created with the name `keys`
119+ ///
120+ /// Note: [`Self::finish`] and [`Self::finish_cloned`] will panic if the
121+ /// field's data type does not match that of `K` or the field is nullable
122+ pub fn with_keys_field ( self , field : impl Into < FieldRef > ) -> Self {
123+ Self {
124+ key_field : Some ( field. into ( ) ) ,
125+ ..self
126+ }
127+ }
128+
129+ /// Override the field passed to [`MapBuilder::new`]
130+ ///
131+ /// By default, a nullable field is created with the name `values`
117132 ///
118133 /// Note: [`Self::finish`] and [`Self::finish_cloned`] will panic if the
119134 /// field's data type does not match that of `V`
@@ -194,11 +209,17 @@ impl<K: ArrayBuilder, V: ArrayBuilder> MapBuilder<K, V> {
194209 keys_arr. null_count( )
195210 ) ;
196211
197- let keys_field = Arc :: new ( Field :: new (
198- self . field_names . key . as_str ( ) ,
199- keys_arr. data_type ( ) . clone ( ) ,
200- false , // always non-nullable
201- ) ) ;
212+ let keys_field = match & self . key_field {
213+ Some ( f) => {
214+ assert ! ( !f. is_nullable( ) , "Keys field must not be nullable" ) ;
215+ f. clone ( )
216+ }
217+ None => Arc :: new ( Field :: new (
218+ self . field_names . key . as_str ( ) ,
219+ keys_arr. data_type ( ) . clone ( ) ,
220+ false , // always non-nullable
221+ ) ) ,
222+ } ;
202223 let values_field = match & self . value_field {
203224 Some ( f) => f. clone ( ) ,
204225 None => Arc :: new ( Field :: new (
@@ -262,10 +283,10 @@ impl<K: ArrayBuilder, V: ArrayBuilder> ArrayBuilder for MapBuilder<K, V> {
262283
263284#[ cfg( test) ]
264285mod tests {
286+ use super :: * ;
265287 use crate :: builder:: { make_builder, Int32Builder , StringBuilder } ;
266288 use crate :: { Int32Array , StringArray } ;
267-
268- use super :: * ;
289+ use std:: collections:: HashMap ;
269290
270291 #[ test]
271292 #[ should_panic( expected = "Keys array must have no null values, found 1 null value(s)" ) ]
@@ -377,4 +398,67 @@ mod tests {
377398 )
378399 ) ;
379400 }
401+
402+ #[ test]
403+ fn test_with_keys_field ( ) {
404+ let mut key_metadata = HashMap :: new ( ) ;
405+ key_metadata. insert ( "foo" . to_string ( ) , "bar" . to_string ( ) ) ;
406+ let key_field = Arc :: new (
407+ Field :: new ( "keys" , DataType :: Int32 , false ) . with_metadata ( key_metadata. clone ( ) ) ,
408+ ) ;
409+ let mut builder = MapBuilder :: new ( None , Int32Builder :: new ( ) , Int32Builder :: new ( ) )
410+ . with_keys_field ( key_field. clone ( ) ) ;
411+ builder. keys ( ) . append_value ( 1 ) ;
412+ builder. values ( ) . append_value ( 2 ) ;
413+ builder. append ( true ) . unwrap ( ) ;
414+ let map = builder. finish ( ) ;
415+
416+ assert_eq ! ( map. len( ) , 1 ) ;
417+ assert_eq ! (
418+ map. data_type( ) ,
419+ & DataType :: Map (
420+ Arc :: new( Field :: new(
421+ "entries" ,
422+ DataType :: Struct (
423+ vec![
424+ Arc :: new(
425+ Field :: new( "keys" , DataType :: Int32 , false )
426+ . with_metadata( key_metadata)
427+ ) ,
428+ Arc :: new( Field :: new( "values" , DataType :: Int32 , true ) )
429+ ]
430+ . into( )
431+ ) ,
432+ false ,
433+ ) ) ,
434+ false
435+ )
436+ ) ;
437+ }
438+
439+ #[ test]
440+ #[ should_panic( expected = "Keys field must not be nullable" ) ]
441+ fn test_with_nullable_keys_field ( ) {
442+ let mut builder = MapBuilder :: new ( None , Int32Builder :: new ( ) , Int32Builder :: new ( ) )
443+ . with_keys_field ( Arc :: new ( Field :: new ( "keys" , DataType :: Int32 , true ) ) ) ;
444+
445+ builder. keys ( ) . append_value ( 1 ) ;
446+ builder. values ( ) . append_value ( 2 ) ;
447+ builder. append ( true ) . unwrap ( ) ;
448+
449+ builder. finish ( ) ;
450+ }
451+
452+ #[ test]
453+ #[ should_panic( expected = "Incorrect datatype" ) ]
454+ fn test_keys_field_type_mismatch ( ) {
455+ let mut builder = MapBuilder :: new ( None , Int32Builder :: new ( ) , Int32Builder :: new ( ) )
456+ . with_keys_field ( Arc :: new ( Field :: new ( "keys" , DataType :: Utf8 , false ) ) ) ;
457+
458+ builder. keys ( ) . append_value ( 1 ) ;
459+ builder. values ( ) . append_value ( 2 ) ;
460+ builder. append ( true ) . unwrap ( ) ;
461+
462+ builder. finish ( ) ;
463+ }
380464}
0 commit comments