datatypes/vectors/operations/
cast.rsmacro_rules! cast_non_constant {
($vector: expr, $to_type: expr) => {{
use arrow::compute;
use snafu::ResultExt;
use crate::data_type::DataType;
use crate::vectors::helper::Helper;
let arrow_array = $vector.to_arrow_array();
let casted = compute::cast(&arrow_array, &$to_type.as_arrow_type())
.context(crate::error::ArrowComputeSnafu)?;
Helper::try_into_vector(casted)
}};
}
pub(crate) use cast_non_constant;
#[cfg(test)]
mod tests {
use std::sync::Arc;
use common_time::date::Date;
use common_time::timestamp::{TimeUnit, Timestamp};
use crate::types::{LogicalPrimitiveType, *};
use crate::vectors::{ConcreteDataType, *};
fn get_cast_values<T>(vector: &VectorRef, dt: &ConcreteDataType) -> Vec<String>
where
T: LogicalPrimitiveType,
{
let c = vector.cast(dt).unwrap();
let a = c.as_any().downcast_ref::<PrimitiveVector<T>>().unwrap();
let mut v: Vec<String> = vec![];
for i in 0..vector.len() {
if a.is_null(i) {
v.push("null".to_string())
} else {
v.push(format!("{}", a.get(i)));
}
}
v
}
#[test]
fn test_cast_from_f64() {
let f64_values: Vec<f64> = vec![
i64::MIN as f64,
i32::MIN as f64,
i16::MIN as f64,
i8::MIN as f64,
0_f64,
u8::MAX as f64,
u16::MAX as f64,
u32::MAX as f64,
u64::MAX as f64,
];
let f64_vector: VectorRef = Arc::new(Float64Vector::from_slice(f64_values));
let f64_expected = vec![
-9223372036854776000.0,
-2147483648.0,
-32768.0,
-128.0,
0.0,
255.0,
65535.0,
4294967295.0,
18446744073709552000.0,
];
assert_eq!(
f64_expected,
get_cast_values::<Float64Type>(&f64_vector, &ConcreteDataType::float64_datatype())
.iter()
.map(|i| i.parse::<f64>().unwrap())
.collect::<Vec<f64>>()
);
let i64_expected = vec![
"-9223372036854775808",
"-2147483648",
"-32768",
"-128",
"0",
"255",
"65535",
"4294967295",
"null",
];
assert_eq!(
i64_expected,
get_cast_values::<Int64Type>(&f64_vector, &ConcreteDataType::int64_datatype())
);
let u64_expected = vec![
"null",
"null",
"null",
"null",
"0",
"255",
"65535",
"4294967295",
"null",
];
assert_eq!(
u64_expected,
get_cast_values::<UInt64Type>(&f64_vector, &ConcreteDataType::uint64_datatype())
);
}
#[test]
fn test_cast_from_date() {
let i32_values: Vec<i32> = vec![
i32::MIN,
i16::MIN as i32,
i8::MIN as i32,
0,
i8::MAX as i32,
i16::MAX as i32,
i32::MAX,
];
let date32_vector: VectorRef = Arc::new(DateVector::from_slice(i32_values));
let i32_expected = vec![
"-2147483648",
"-32768",
"-128",
"0",
"127",
"32767",
"2147483647",
];
assert_eq!(
i32_expected,
get_cast_values::<Int32Type>(&date32_vector, &ConcreteDataType::int32_datatype()),
);
let i64_expected = vec![
"-2147483648",
"-32768",
"-128",
"0",
"127",
"32767",
"2147483647",
];
assert_eq!(
i64_expected,
get_cast_values::<Int64Type>(&date32_vector, &ConcreteDataType::int64_datatype()),
);
}
#[test]
fn test_cast_timestamp_to_date32() {
let vector =
TimestampMillisecondVector::from(vec![Some(864000000005), Some(1545696000001), None]);
let b = vector.cast(&ConcreteDataType::date_datatype()).unwrap();
let c = b.as_any().downcast_ref::<DateVector>().unwrap();
assert_eq!(Value::Date(Date::from(10000)), c.get(0));
assert_eq!(Value::Date(Date::from(17890)), c.get(1));
assert!(c.is_null(2));
}
#[test]
fn test_cast_string_to_timestamp() {
let a1 = Arc::new(StringVector::from(vec![
Some("2020-09-08T12:00:00+00:00"),
Some("Not a valid date"),
None,
])) as VectorRef;
let a2 = Arc::new(StringVector::from(vec![
Some("2020-09-08T12:00:00+00:00"),
Some("Not a valid date"),
None,
])) as VectorRef;
for array in &[a1, a2] {
let to_type = ConcreteDataType::timestamp_nanosecond_datatype();
let b = array.cast(&to_type).unwrap();
let c = b
.as_any()
.downcast_ref::<TimestampNanosecondVector>()
.unwrap();
assert_eq!(
Value::Timestamp(Timestamp::new(1599566400000000000, TimeUnit::Nanosecond)),
c.get(0)
);
assert!(c.is_null(1));
assert!(c.is_null(2));
}
}
#[test]
fn test_safe_cast_to_null() {
let string_vector = Arc::new(StringVector::from(vec![
Some("1"),
Some("hello"),
Some(&i64::MAX.to_string()),
None,
])) as VectorRef;
let to_type = ConcreteDataType::int32_datatype();
let b = string_vector.cast(&to_type).unwrap();
let c = b.as_any().downcast_ref::<Int32Vector>().unwrap();
assert_eq!(Value::Int32(1), c.get(0));
assert_eq!(Value::Null, c.get(1));
assert_eq!(Value::Null, c.get(2));
assert_eq!(Value::Null, c.get(3));
}
}