Skip to content

Commit

Permalink
support cast/try_cast for decimal: signed numeric to decimal (#1442)
Browse files Browse the repository at this point in the history
* support cast/try_cast for decimal: signed numeric to decimal

* add test case

* change test case

* change dependency

* remove useless code

* restore dependency
  • Loading branch information
liukun4515 authored Jan 14, 2022
1 parent 811bb51 commit 0bddfb7
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 3 deletions.
128 changes: 127 additions & 1 deletion datafusion/src/physical_plan/expressions/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ mod tests {
use crate::physical_plan::expressions::col;
use arrow::array::{StringArray, Time64NanosecondArray};
use arrow::{
array::{Array, Int32Array, Int64Array, TimestampNanosecondArray, UInt32Array},
array::{
Array, DecimalArray, Float32Array, Float64Array, Int16Array, Int32Array,
Int64Array, Int8Array, TimestampNanosecondArray, UInt32Array,
},
datatypes::*,
};

Expand Down Expand Up @@ -217,6 +220,129 @@ mod tests {
}};
}

#[test]
fn test_cast_numeric_to_decimal() -> Result<()> {
// int8
generic_test_cast!(
Int8Array,
DataType::Int8,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(3, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);

// int16
generic_test_cast!(
Int16Array,
DataType::Int16,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(5, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);

// int32
generic_test_cast!(
Int32Array,
DataType::Int32,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(10, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);

// int64
generic_test_cast!(
Int64Array,
DataType::Int64,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(20, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);

// int64 to different scale
generic_test_cast!(
Int64Array,
DataType::Int64,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(20, 2),
vec![
Some(100_i128),
Some(200_i128),
Some(300_i128),
Some(400_i128),
Some(500_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);

// float32
generic_test_cast!(
Float32Array,
DataType::Float32,
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
DecimalArray,
DataType::Decimal(10, 2),
vec![
Some(150_i128),
Some(250_i128),
Some(300_i128),
Some(112_i128),
Some(550_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);

// float64
generic_test_cast!(
Float64Array,
DataType::Float64,
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
DecimalArray,
DataType::Decimal(20, 4),
vec![
Some(15000_i128),
Some(25000_i128),
Some(30000_i128),
Some(11234_i128),
Some(55000_i128),
],
DEFAULT_DATAFUSION_CAST_OPTIONS
);
Ok(())
}

#[test]
fn test_cast_i32_u32() -> Result<()> {
generic_test_cast!(
Expand Down
123 changes: 121 additions & 2 deletions datafusion/src/physical_plan/expressions/try_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,12 @@ mod tests {
use super::*;
use crate::error::Result;
use crate::physical_plan::expressions::col;
use arrow::array::{StringArray, Time64NanosecondArray};
use arrow::array::{Float32Array, Float64Array, StringArray, Time64NanosecondArray};
use arrow::{
array::{Array, Int32Array, Int64Array, TimestampNanosecondArray, UInt32Array},
array::{
Array, DecimalArray, Int16Array, Int32Array, Int64Array, Int8Array,
TimestampNanosecondArray, UInt32Array,
},
datatypes::*,
};

Expand Down Expand Up @@ -175,6 +178,122 @@ mod tests {
}};
}

#[test]
fn test_try_cast_numeric_to_decimal() -> Result<()> {
// int8
generic_test_cast!(
Int8Array,
DataType::Int8,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(3, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
]
);

// int16
generic_test_cast!(
Int16Array,
DataType::Int16,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(5, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
]
);

// int32
generic_test_cast!(
Int32Array,
DataType::Int32,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(10, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
]
);

// int64
generic_test_cast!(
Int64Array,
DataType::Int64,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(20, 0),
vec![
Some(1_i128),
Some(2_i128),
Some(3_i128),
Some(4_i128),
Some(5_i128),
]
);

// int64 to different scale
generic_test_cast!(
Int64Array,
DataType::Int64,
vec![1, 2, 3, 4, 5],
DecimalArray,
DataType::Decimal(20, 2),
vec![
Some(100_i128),
Some(200_i128),
Some(300_i128),
Some(400_i128),
Some(500_i128),
]
);

// float32
generic_test_cast!(
Float32Array,
DataType::Float32,
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
DecimalArray,
DataType::Decimal(10, 2),
vec![
Some(150_i128),
Some(250_i128),
Some(300_i128),
Some(112_i128),
Some(550_i128),
]
);

// float64
generic_test_cast!(
Float64Array,
DataType::Float64,
vec![1.5, 2.5, 3.0, 1.123_456_8, 5.50],
DecimalArray,
DataType::Decimal(20, 4),
vec![
Some(15000_i128),
Some(25000_i128),
Some(30000_i128),
Some(11234_i128),
Some(55000_i128),
]
);
Ok(())
}

#[test]
fn test_cast_i32_u32() -> Result<()> {
generic_test_cast!(
Expand Down

0 comments on commit 0bddfb7

Please sign in to comment.