Skip to content

Commit 0bddfb7

Browse files
authored
support cast/try_cast for decimal: signed numeric to decimal (#1442)
* support cast/try_cast for decimal: signed numeric to decimal * add test case * change test case * change dependency * remove useless code * restore dependency
1 parent 811bb51 commit 0bddfb7

File tree

2 files changed

+248
-3
lines changed

2 files changed

+248
-3
lines changed

datafusion/src/physical_plan/expressions/cast.rs

+127-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ mod tests {
162162
use crate::physical_plan::expressions::col;
163163
use arrow::array::{StringArray, Time64NanosecondArray};
164164
use arrow::{
165-
array::{Array, Int32Array, Int64Array, TimestampNanosecondArray, UInt32Array},
165+
array::{
166+
Array, DecimalArray, Float32Array, Float64Array, Int16Array, Int32Array,
167+
Int64Array, Int8Array, TimestampNanosecondArray, UInt32Array,
168+
},
166169
datatypes::*,
167170
};
168171

@@ -217,6 +220,129 @@ mod tests {
217220
}};
218221
}
219222

223+
#[test]
224+
fn test_cast_numeric_to_decimal() -> Result<()> {
225+
// int8
226+
generic_test_cast!(
227+
Int8Array,
228+
DataType::Int8,
229+
vec![1, 2, 3, 4, 5],
230+
DecimalArray,
231+
DataType::Decimal(3, 0),
232+
vec![
233+
Some(1_i128),
234+
Some(2_i128),
235+
Some(3_i128),
236+
Some(4_i128),
237+
Some(5_i128),
238+
],
239+
DEFAULT_DATAFUSION_CAST_OPTIONS
240+
);
241+
242+
// int16
243+
generic_test_cast!(
244+
Int16Array,
245+
DataType::Int16,
246+
vec![1, 2, 3, 4, 5],
247+
DecimalArray,
248+
DataType::Decimal(5, 0),
249+
vec![
250+
Some(1_i128),
251+
Some(2_i128),
252+
Some(3_i128),
253+
Some(4_i128),
254+
Some(5_i128),
255+
],
256+
DEFAULT_DATAFUSION_CAST_OPTIONS
257+
);
258+
259+
// int32
260+
generic_test_cast!(
261+
Int32Array,
262+
DataType::Int32,
263+
vec![1, 2, 3, 4, 5],
264+
DecimalArray,
265+
DataType::Decimal(10, 0),
266+
vec![
267+
Some(1_i128),
268+
Some(2_i128),
269+
Some(3_i128),
270+
Some(4_i128),
271+
Some(5_i128),
272+
],
273+
DEFAULT_DATAFUSION_CAST_OPTIONS
274+
);
275+
276+
// int64
277+
generic_test_cast!(
278+
Int64Array,
279+
DataType::Int64,
280+
vec![1, 2, 3, 4, 5],
281+
DecimalArray,
282+
DataType::Decimal(20, 0),
283+
vec![
284+
Some(1_i128),
285+
Some(2_i128),
286+
Some(3_i128),
287+
Some(4_i128),
288+
Some(5_i128),
289+
],
290+
DEFAULT_DATAFUSION_CAST_OPTIONS
291+
);
292+
293+
// int64 to different scale
294+
generic_test_cast!(
295+
Int64Array,
296+
DataType::Int64,
297+
vec![1, 2, 3, 4, 5],
298+
DecimalArray,
299+
DataType::Decimal(20, 2),
300+
vec![
301+
Some(100_i128),
302+
Some(200_i128),
303+
Some(300_i128),
304+
Some(400_i128),
305+
Some(500_i128),
306+
],
307+
DEFAULT_DATAFUSION_CAST_OPTIONS
308+
);
309+
310+
// float32
311+
generic_test_cast!(
312+
Float32Array,
313+
DataType::Float32,
314+
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
315+
DecimalArray,
316+
DataType::Decimal(10, 2),
317+
vec![
318+
Some(150_i128),
319+
Some(250_i128),
320+
Some(300_i128),
321+
Some(112_i128),
322+
Some(550_i128),
323+
],
324+
DEFAULT_DATAFUSION_CAST_OPTIONS
325+
);
326+
327+
// float64
328+
generic_test_cast!(
329+
Float64Array,
330+
DataType::Float64,
331+
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
332+
DecimalArray,
333+
DataType::Decimal(20, 4),
334+
vec![
335+
Some(15000_i128),
336+
Some(25000_i128),
337+
Some(30000_i128),
338+
Some(11234_i128),
339+
Some(55000_i128),
340+
],
341+
DEFAULT_DATAFUSION_CAST_OPTIONS
342+
);
343+
Ok(())
344+
}
345+
220346
#[test]
221347
fn test_cast_i32_u32() -> Result<()> {
222348
generic_test_cast!(

datafusion/src/physical_plan/expressions/try_cast.rs

+121-2
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,12 @@ mod tests {
119119
use super::*;
120120
use crate::error::Result;
121121
use crate::physical_plan::expressions::col;
122-
use arrow::array::{StringArray, Time64NanosecondArray};
122+
use arrow::array::{Float32Array, Float64Array, StringArray, Time64NanosecondArray};
123123
use arrow::{
124-
array::{Array, Int32Array, Int64Array, TimestampNanosecondArray, UInt32Array},
124+
array::{
125+
Array, DecimalArray, Int16Array, Int32Array, Int64Array, Int8Array,
126+
TimestampNanosecondArray, UInt32Array,
127+
},
125128
datatypes::*,
126129
};
127130

@@ -175,6 +178,122 @@ mod tests {
175178
}};
176179
}
177180

181+
#[test]
182+
fn test_try_cast_numeric_to_decimal() -> Result<()> {
183+
// int8
184+
generic_test_cast!(
185+
Int8Array,
186+
DataType::Int8,
187+
vec![1, 2, 3, 4, 5],
188+
DecimalArray,
189+
DataType::Decimal(3, 0),
190+
vec![
191+
Some(1_i128),
192+
Some(2_i128),
193+
Some(3_i128),
194+
Some(4_i128),
195+
Some(5_i128),
196+
]
197+
);
198+
199+
// int16
200+
generic_test_cast!(
201+
Int16Array,
202+
DataType::Int16,
203+
vec![1, 2, 3, 4, 5],
204+
DecimalArray,
205+
DataType::Decimal(5, 0),
206+
vec![
207+
Some(1_i128),
208+
Some(2_i128),
209+
Some(3_i128),
210+
Some(4_i128),
211+
Some(5_i128),
212+
]
213+
);
214+
215+
// int32
216+
generic_test_cast!(
217+
Int32Array,
218+
DataType::Int32,
219+
vec![1, 2, 3, 4, 5],
220+
DecimalArray,
221+
DataType::Decimal(10, 0),
222+
vec![
223+
Some(1_i128),
224+
Some(2_i128),
225+
Some(3_i128),
226+
Some(4_i128),
227+
Some(5_i128),
228+
]
229+
);
230+
231+
// int64
232+
generic_test_cast!(
233+
Int64Array,
234+
DataType::Int64,
235+
vec![1, 2, 3, 4, 5],
236+
DecimalArray,
237+
DataType::Decimal(20, 0),
238+
vec![
239+
Some(1_i128),
240+
Some(2_i128),
241+
Some(3_i128),
242+
Some(4_i128),
243+
Some(5_i128),
244+
]
245+
);
246+
247+
// int64 to different scale
248+
generic_test_cast!(
249+
Int64Array,
250+
DataType::Int64,
251+
vec![1, 2, 3, 4, 5],
252+
DecimalArray,
253+
DataType::Decimal(20, 2),
254+
vec![
255+
Some(100_i128),
256+
Some(200_i128),
257+
Some(300_i128),
258+
Some(400_i128),
259+
Some(500_i128),
260+
]
261+
);
262+
263+
// float32
264+
generic_test_cast!(
265+
Float32Array,
266+
DataType::Float32,
267+
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
268+
DecimalArray,
269+
DataType::Decimal(10, 2),
270+
vec![
271+
Some(150_i128),
272+
Some(250_i128),
273+
Some(300_i128),
274+
Some(112_i128),
275+
Some(550_i128),
276+
]
277+
);
278+
279+
// float64
280+
generic_test_cast!(
281+
Float64Array,
282+
DataType::Float64,
283+
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
284+
DecimalArray,
285+
DataType::Decimal(20, 4),
286+
vec![
287+
Some(15000_i128),
288+
Some(25000_i128),
289+
Some(30000_i128),
290+
Some(11234_i128),
291+
Some(55000_i128),
292+
]
293+
);
294+
Ok(())
295+
}
296+
178297
#[test]
179298
fn test_cast_i32_u32() -> Result<()> {
180299
generic_test_cast!(

0 commit comments

Comments
 (0)