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