17
17
18
18
use std:: sync:: Arc ;
19
19
20
+ use crate :: {
21
+ cast_conversion_nongeneric, cast_conversion_string, decimal_to_variant_decimal,
22
+ generic_conversion_array, non_generic_conversion_array, primitive_conversion,
23
+ } ;
20
24
use crate :: { VariantArray , VariantArrayBuilder } ;
21
25
use arrow:: array:: {
22
26
Array , AsArray , TimestampMicrosecondArray , TimestampMillisecondArray , TimestampNanosecondArray ,
@@ -39,55 +43,6 @@ use parquet_variant::{
39
43
Variant , VariantBuilder , VariantDecimal16 , VariantDecimal4 , VariantDecimal8 ,
40
44
} ;
41
45
42
- /// Convert the input array of a specific primitive type to a `VariantArray`
43
- /// row by row
44
- macro_rules! primitive_conversion {
45
- ( $t: ty, $input: expr, $builder: expr) => { {
46
- let array = $input. as_primitive:: <$t>( ) ;
47
- for i in 0 ..array. len( ) {
48
- if array. is_null( i) {
49
- $builder. append_null( ) ;
50
- continue ;
51
- }
52
- $builder. append_variant( Variant :: from( array. value( i) ) ) ;
53
- }
54
- } } ;
55
- }
56
-
57
- /// Convert the input array to a `VariantArray` row by row, using `method`
58
- /// requiring a generic type to downcast the generic array to a specific
59
- /// array type and `cast_fn` to transform each element to a type compatible with Variant
60
- macro_rules! generic_conversion {
61
- ( $t: ty, $method: ident, $cast_fn: expr, $input: expr, $builder: expr) => { {
62
- let array = $input. $method:: <$t>( ) ;
63
- for i in 0 ..array. len( ) {
64
- if array. is_null( i) {
65
- $builder. append_null( ) ;
66
- continue ;
67
- }
68
- let cast_value = $cast_fn( array. value( i) ) ;
69
- $builder. append_variant( Variant :: from( cast_value) ) ;
70
- }
71
- } } ;
72
- }
73
-
74
- /// Convert the input array to a `VariantArray` row by row, using `method`
75
- /// not requiring a generic type to downcast the generic array to a specific
76
- /// array type and `cast_fn` to transform each element to a type compatible with Variant
77
- macro_rules! non_generic_conversion {
78
- ( $method: ident, $cast_fn: expr, $input: expr, $builder: expr) => { {
79
- let array = $input. $method( ) ;
80
- for i in 0 ..array. len( ) {
81
- if array. is_null( i) {
82
- $builder. append_null( ) ;
83
- continue ;
84
- }
85
- let cast_value = $cast_fn( array. value( i) ) ;
86
- $builder. append_variant( Variant :: from( cast_value) ) ;
87
- }
88
- } } ;
89
- }
90
-
91
46
fn convert_timestamp (
92
47
time_unit : & TimeUnit ,
93
48
time_zone : & Option < Arc < str > > ,
@@ -156,61 +111,6 @@ fn convert_timestamp(
156
111
}
157
112
}
158
113
159
- /// Convert a decimal value to a `VariantDecimal`
160
- macro_rules! decimal_to_variant_decimal {
161
- ( $v: ident, $scale: expr, $value_type: ty, $variant_type: ty) => {
162
- if * $scale < 0 {
163
- // For negative scale, we need to multiply the value by 10^|scale|
164
- // For example: 123 with scale -2 becomes 12300
165
- let multiplier = ( 10 as $value_type) . pow( ( -* $scale) as u32 ) ;
166
- // Check for overflow
167
- if $v > 0 && $v > <$value_type>:: MAX / multiplier {
168
- return Variant :: Null ;
169
- }
170
- if $v < 0 && $v < <$value_type>:: MIN / multiplier {
171
- return Variant :: Null ;
172
- }
173
- <$variant_type>:: try_new( $v * multiplier, 0 )
174
- . map( |v| v. into( ) )
175
- . unwrap_or( Variant :: Null )
176
- } else {
177
- <$variant_type>:: try_new( $v, * $scale as u8 )
178
- . map( |v| v. into( ) )
179
- . unwrap_or( Variant :: Null )
180
- }
181
- } ;
182
- }
183
-
184
- /// Convert arrays that don't need generic type parameters
185
- macro_rules! cast_conversion_nongeneric {
186
- ( $method: ident, $cast_fn: expr, $input: expr, $builder: expr) => { {
187
- let array = $input. $method( ) ;
188
- for i in 0 ..array. len( ) {
189
- if array. is_null( i) {
190
- $builder. append_null( ) ;
191
- continue ;
192
- }
193
- let cast_value = $cast_fn( array. value( i) ) ;
194
- $builder. append_variant( Variant :: from( cast_value) ) ;
195
- }
196
- } } ;
197
- }
198
-
199
- /// Convert string arrays using the offset size as the type parameter
200
- macro_rules! cast_conversion_string {
201
- ( $offset_type: ty, $method: ident, $cast_fn: expr, $input: expr, $builder: expr) => { {
202
- let array = $input. $method:: <$offset_type>( ) ;
203
- for i in 0 ..array. len( ) {
204
- if array. is_null( i) {
205
- $builder. append_null( ) ;
206
- continue ;
207
- }
208
- let cast_value = $cast_fn( array. value( i) ) ;
209
- $builder. append_variant( Variant :: from( cast_value) ) ;
210
- }
211
- } } ;
212
- }
213
-
214
114
/// Casts a typed arrow [`Array`] to a [`VariantArray`]. This is useful when you
215
115
/// need to convert a specific data type
216
116
///
@@ -247,17 +147,17 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
247
147
// todo: handle other types like Boolean, Date, Timestamp, etc.
248
148
match input_type {
249
149
DataType :: Boolean => {
250
- non_generic_conversion ! ( as_boolean, |v| v, input, builder) ;
150
+ non_generic_conversion_array ! ( as_boolean, |v| v, input, builder) ;
251
151
}
252
152
253
153
DataType :: Binary => {
254
- generic_conversion ! ( BinaryType , as_bytes, |v| v, input, builder) ;
154
+ generic_conversion_array ! ( BinaryType , as_bytes, |v| v, input, builder) ;
255
155
}
256
156
DataType :: LargeBinary => {
257
- generic_conversion ! ( LargeBinaryType , as_bytes, |v| v, input, builder) ;
157
+ generic_conversion_array ! ( LargeBinaryType , as_bytes, |v| v, input, builder) ;
258
158
}
259
159
DataType :: BinaryView => {
260
- generic_conversion ! ( BinaryViewType , as_byte_view, |v| v, input, builder) ;
160
+ generic_conversion_array ! ( BinaryViewType , as_byte_view, |v| v, input, builder) ;
261
161
}
262
162
DataType :: Int8 => {
263
163
primitive_conversion ! ( Int8Type , input, builder) ;
@@ -284,7 +184,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
284
184
primitive_conversion ! ( UInt64Type , input, builder) ;
285
185
}
286
186
DataType :: Float16 => {
287
- generic_conversion ! (
187
+ generic_conversion_array ! (
288
188
Float16Type ,
289
189
as_primitive,
290
190
|v: f16| -> f32 { v. into( ) } ,
@@ -299,7 +199,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
299
199
primitive_conversion ! ( Float64Type , input, builder) ;
300
200
}
301
201
DataType :: Decimal32 ( _, scale) => {
302
- generic_conversion ! (
202
+ generic_conversion_array ! (
303
203
Decimal32Type ,
304
204
as_primitive,
305
205
|v| decimal_to_variant_decimal!( v, scale, i32 , VariantDecimal4 ) ,
@@ -308,7 +208,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
308
208
) ;
309
209
}
310
210
DataType :: Decimal64 ( _, scale) => {
311
- generic_conversion ! (
211
+ generic_conversion_array ! (
312
212
Decimal64Type ,
313
213
as_primitive,
314
214
|v| decimal_to_variant_decimal!( v, scale, i64 , VariantDecimal8 ) ,
@@ -317,7 +217,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
317
217
) ;
318
218
}
319
219
DataType :: Decimal128 ( _, scale) => {
320
- generic_conversion ! (
220
+ generic_conversion_array ! (
321
221
Decimal128Type ,
322
222
as_primitive,
323
223
|v| decimal_to_variant_decimal!( v, scale, i128 , VariantDecimal16 ) ,
@@ -326,7 +226,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
326
226
) ;
327
227
}
328
228
DataType :: Decimal256 ( _, scale) => {
329
- generic_conversion ! (
229
+ generic_conversion_array ! (
330
230
Decimal256Type ,
331
231
as_primitive,
332
232
|v: i256| {
@@ -344,7 +244,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
344
244
) ;
345
245
}
346
246
DataType :: FixedSizeBinary ( _) => {
347
- non_generic_conversion ! ( as_fixed_size_binary, |v| v, input, builder) ;
247
+ non_generic_conversion_array ! ( as_fixed_size_binary, |v| v, input, builder) ;
348
248
}
349
249
DataType :: Null => {
350
250
for _ in 0 ..input. len ( ) {
@@ -357,7 +257,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
357
257
DataType :: Time32 ( unit) => {
358
258
match * unit {
359
259
TimeUnit :: Second => {
360
- generic_conversion ! (
260
+ generic_conversion_array ! (
361
261
Time32SecondType ,
362
262
as_primitive,
363
263
// nano second are always 0
@@ -367,7 +267,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
367
267
) ;
368
268
}
369
269
TimeUnit :: Millisecond => {
370
- generic_conversion ! (
270
+ generic_conversion_array ! (
371
271
Time32MillisecondType ,
372
272
as_primitive,
373
273
|v| NaiveTime :: from_num_seconds_from_midnight_opt(
@@ -390,7 +290,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
390
290
DataType :: Time64 ( unit) => {
391
291
match * unit {
392
292
TimeUnit :: Microsecond => {
393
- generic_conversion ! (
293
+ generic_conversion_array ! (
394
294
Time64MicrosecondType ,
395
295
as_primitive,
396
296
|v| NaiveTime :: from_num_seconds_from_midnight_opt(
@@ -403,7 +303,7 @@ pub fn cast_to_variant(input: &dyn Array) -> Result<VariantArray, ArrowError> {
403
303
) ;
404
304
}
405
305
TimeUnit :: Nanosecond => {
406
- generic_conversion ! (
306
+ generic_conversion_array ! (
407
307
Time64NanosecondType ,
408
308
as_primitive,
409
309
|v| NaiveTime :: from_num_seconds_from_midnight_opt(
0 commit comments