@@ -7,16 +7,19 @@ use arrow_array::ArrayRef as ArrowArrayRef;
77use arrow_array:: DictionaryArray ;
88use arrow_array:: PrimitiveArray ;
99use arrow_array:: cast:: AsArray ;
10+ use arrow_array:: new_empty_array;
1011use arrow_array:: new_null_array;
1112use arrow_array:: types:: * ;
1213use arrow_schema:: DataType ;
1314use vortex_array:: ArrayRef ;
1415use vortex_array:: ExecutionCtx ;
1516use vortex_array:: IntoArray ;
17+ use vortex_array:: arrays:: Chunked ;
1618use vortex_array:: arrays:: Constant ;
1719use vortex_array:: arrays:: ConstantArray ;
1820use vortex_array:: arrays:: Dict ;
1921use vortex_array:: arrays:: DictArray ;
22+ use vortex_array:: arrays:: chunked:: ChunkedArrayExt ;
2023use vortex_array:: arrays:: dict:: DictArraySlotsExt ;
2124use vortex_array:: matcher:: Matcher ;
2225use vortex_error:: VortexError ;
@@ -32,7 +35,7 @@ impl Matcher for ArrowDictExportable {
3235 type Match < ' a > = & ' a ArrayRef ;
3336
3437 fn try_match ( array : & ArrayRef ) -> Option < Self :: Match < ' _ > > {
35- ( array. is :: < Dict > ( ) || array. is :: < Constant > ( ) ) . then_some ( array)
38+ ( array. is :: < Dict > ( ) || array. is :: < Chunked > ( ) || array . is :: < Constant > ( ) ) . then_some ( array)
3639 }
3740}
3841
@@ -52,6 +55,10 @@ pub(super) fn to_arrow_dictionary(
5255 Ok ( constant) => return constant_to_dict ( constant, codes_type, values_type, ctx) ,
5356 Err ( array) => array,
5457 } ;
58+ let array = match array. try_downcast :: < Chunked > ( ) {
59+ Ok ( chunked) => return chunked_to_dict ( chunked, codes_type, values_type, ctx) ,
60+ Err ( array) => array,
61+ } ;
5562
5663 // Otherwise, we should try and build a dictionary.
5764 // Arrow hides this functionality inside the cast module!
@@ -85,6 +92,40 @@ fn constant_to_dict(
8592 make_dict_array ( codes_type, codes, values)
8693}
8794
95+ /// Convert a chunked array to an Arrow dictionary array by exporting each chunk separately.
96+ fn chunked_to_dict (
97+ array : vortex_array:: arrays:: ChunkedArray ,
98+ codes_type : & DataType ,
99+ values_type : & DataType ,
100+ ctx : & mut ExecutionCtx ,
101+ ) -> VortexResult < ArrowArrayRef > {
102+ let mut arrow_chunks = Vec :: with_capacity ( array. nchunks ( ) ) ;
103+ for chunk in array. non_empty_chunks ( ) {
104+ arrow_chunks. push ( to_arrow_dictionary (
105+ chunk. clone ( ) ,
106+ codes_type,
107+ values_type,
108+ ctx,
109+ ) ?) ;
110+ }
111+
112+ if arrow_chunks. is_empty ( ) {
113+ return Ok ( new_empty_array ( & DataType :: Dictionary (
114+ Box :: new ( codes_type. clone ( ) ) ,
115+ Box :: new ( values_type. clone ( ) ) ,
116+ ) ) ) ;
117+ }
118+ if let [ arrow_chunk] = arrow_chunks. as_slice ( ) {
119+ return Ok ( Arc :: clone ( arrow_chunk) ) ;
120+ }
121+
122+ let refs = arrow_chunks
123+ . iter ( )
124+ . map ( |array| array. as_ref ( ) )
125+ . collect :: < Vec < _ > > ( ) ;
126+ Ok ( arrow_select:: concat:: concat ( & refs) ?)
127+ }
128+
88129/// Convert a Vortex dictionary array to an Arrow dictionary array.
89130fn dict_to_dict (
90131 array : DictArray ,
0 commit comments