datatypes/vectors/operations/
cast.rs1macro_rules! cast_non_constant {
16 ($vector: expr, $to_type: expr) => {{
17 use arrow::compute;
18 use snafu::ResultExt;
19
20 use crate::data_type::DataType;
21 use crate::vectors::helper::Helper;
22
23 let arrow_array = $vector.to_arrow_array();
24 let casted = compute::cast(&arrow_array, &$to_type.as_arrow_type())
25 .context(crate::error::ArrowComputeSnafu)?;
26 Helper::try_into_vector(casted)
27 }};
28}
29
30pub(crate) use cast_non_constant;
31
32#[cfg(test)]
36mod tests {
37 use std::sync::Arc;
38
39 use common_time::date::Date;
40 use common_time::timestamp::{TimeUnit, Timestamp};
41
42 use crate::types::{LogicalPrimitiveType, *};
43 use crate::vectors::{ConcreteDataType, *};
44
45 fn get_cast_values<T>(vector: &VectorRef, dt: &ConcreteDataType) -> Vec<String>
46 where
47 T: LogicalPrimitiveType,
48 {
49 let c = vector.cast(dt).unwrap();
50 let a = c.as_any().downcast_ref::<PrimitiveVector<T>>().unwrap();
51 let mut v: Vec<String> = vec![];
52 for i in 0..vector.len() {
53 if a.is_null(i) {
54 v.push("null".to_string())
55 } else {
56 v.push(format!("{}", a.get(i)));
57 }
58 }
59 v
60 }
61
62 #[test]
63 fn test_cast_from_f64() {
64 let f64_values: Vec<f64> = vec![
65 i64::MIN as f64,
66 i32::MIN as f64,
67 i16::MIN as f64,
68 i8::MIN as f64,
69 0_f64,
70 u8::MAX as f64,
71 u16::MAX as f64,
72 u32::MAX as f64,
73 u64::MAX as f64,
74 ];
75 let f64_vector: VectorRef = Arc::new(Float64Vector::from_slice(f64_values));
76
77 let f64_expected = vec![
78 -9223372036854776000.0,
79 -2147483648.0,
80 -32768.0,
81 -128.0,
82 0.0,
83 255.0,
84 65535.0,
85 4294967295.0,
86 18446744073709552000.0,
87 ];
88 assert_eq!(
89 f64_expected,
90 get_cast_values::<Float64Type>(&f64_vector, &ConcreteDataType::float64_datatype())
91 .iter()
92 .map(|i| i.parse::<f64>().unwrap())
93 .collect::<Vec<f64>>()
94 );
95
96 let i64_expected = vec![
97 "-9223372036854775808",
98 "-2147483648",
99 "-32768",
100 "-128",
101 "0",
102 "255",
103 "65535",
104 "4294967295",
105 "null",
106 ];
107 assert_eq!(
108 i64_expected,
109 get_cast_values::<Int64Type>(&f64_vector, &ConcreteDataType::int64_datatype())
110 );
111
112 let u64_expected = vec![
113 "null",
114 "null",
115 "null",
116 "null",
117 "0",
118 "255",
119 "65535",
120 "4294967295",
121 "null",
122 ];
123 assert_eq!(
124 u64_expected,
125 get_cast_values::<UInt64Type>(&f64_vector, &ConcreteDataType::uint64_datatype())
126 );
127 }
128
129 #[test]
130 fn test_cast_from_date() {
131 let i32_values: Vec<i32> = vec![
132 i32::MIN,
133 i16::MIN as i32,
134 i8::MIN as i32,
135 0,
136 i8::MAX as i32,
137 i16::MAX as i32,
138 i32::MAX,
139 ];
140 let date32_vector: VectorRef = Arc::new(DateVector::from_slice(i32_values));
141
142 let i32_expected = vec![
143 "-2147483648",
144 "-32768",
145 "-128",
146 "0",
147 "127",
148 "32767",
149 "2147483647",
150 ];
151 assert_eq!(
152 i32_expected,
153 get_cast_values::<Int32Type>(&date32_vector, &ConcreteDataType::int32_datatype()),
154 );
155
156 let i64_expected = vec![
157 "-2147483648",
158 "-32768",
159 "-128",
160 "0",
161 "127",
162 "32767",
163 "2147483647",
164 ];
165 assert_eq!(
166 i64_expected,
167 get_cast_values::<Int64Type>(&date32_vector, &ConcreteDataType::int64_datatype()),
168 );
169 }
170
171 #[test]
172 fn test_cast_timestamp_to_date32() {
173 let vector =
174 TimestampMillisecondVector::from(vec![Some(864000000005), Some(1545696000001), None]);
175 let b = vector.cast(&ConcreteDataType::date_datatype()).unwrap();
176 let c = b.as_any().downcast_ref::<DateVector>().unwrap();
177 assert_eq!(Value::Date(Date::from(10000)), c.get(0));
178 assert_eq!(Value::Date(Date::from(17890)), c.get(1));
179 assert!(c.is_null(2));
180 }
181
182 #[test]
183 fn test_cast_string_to_timestamp() {
184 let a1 = Arc::new(StringVector::from(vec![
185 Some("2020-09-08T12:00:00+00:00"),
186 Some("Not a valid date"),
187 None,
188 ])) as VectorRef;
189 let a2 = Arc::new(StringVector::from(vec![
190 Some("2020-09-08T12:00:00+00:00"),
191 Some("Not a valid date"),
192 None,
193 ])) as VectorRef;
194
195 for array in &[a1, a2] {
196 let to_type = ConcreteDataType::timestamp_nanosecond_datatype();
197 let b = array.cast(&to_type).unwrap();
198 let c = b
199 .as_any()
200 .downcast_ref::<TimestampNanosecondVector>()
201 .unwrap();
202 assert_eq!(
203 Value::Timestamp(Timestamp::new(1599566400000000000, TimeUnit::Nanosecond)),
204 c.get(0)
205 );
206 assert!(c.is_null(1));
207 assert!(c.is_null(2));
208 }
209 }
210
211 #[test]
212 fn test_safe_cast_to_null() {
213 let string_vector = Arc::new(StringVector::from(vec![
214 Some("1"),
215 Some("hello"),
216 Some(&i64::MAX.to_string()),
217 None,
218 ])) as VectorRef;
219 let to_type = ConcreteDataType::int32_datatype();
220 let b = string_vector.cast(&to_type).unwrap();
221 let c = b.as_any().downcast_ref::<Int32Vector>().unwrap();
222 assert_eq!(Value::Int32(1), c.get(0));
223 assert_eq!(Value::Null, c.get(1));
224 assert_eq!(Value::Null, c.get(2));
225 assert_eq!(Value::Null, c.get(3));
226 }
227}