1use std::sync::Arc;
7
8use arrow::compute::cast;
9use arrow_array::{ArrayRef, cast::AsArray};
10use arrow_schema::{DataType, TimeUnit};
11use datafusion_common::ScalarValue;
12use half::f16;
13
14const MS_PER_DAY: i64 = 86400000;
15
16const F16_OVERFLOW_THRESHOLD: f64 = 65520.0;
20
21fn nearest_finite_f16(value: f64) -> f16 {
37 let start = f16::from_f64_const(value);
38 debug_assert!(
39 start.is_finite(),
40 "caller must reject the overflow range before calling: {value}"
41 );
42 let mut best = start;
43 let mut best_distance = (value - start.to_f64()).abs();
44 let start_bits = start.to_bits();
45 for candidate in [start_bits.wrapping_sub(1), start_bits.wrapping_add(1)].map(f16::from_bits) {
49 if !candidate.is_finite() {
50 continue;
51 }
52 let distance = (value - candidate.to_f64()).abs();
53 let wins =
54 distance < best_distance || (distance == best_distance && candidate.to_bits() & 1 == 0);
55 if wins {
56 best = candidate;
57 best_distance = distance;
58 }
59 }
60 best
61}
62
63fn coerce_to_f16(value: f64) -> Option<f16> {
82 if value.is_nan() {
83 return Some(f16::NAN);
84 }
85 if value.is_infinite() {
86 return Some(if value.is_sign_positive() {
87 f16::INFINITY
88 } else {
89 f16::NEG_INFINITY
90 });
91 }
92 if value.abs() >= F16_OVERFLOW_THRESHOLD {
93 return None;
94 }
95 let nearest = nearest_finite_f16(value);
96 if nearest == f16::ZERO && value != 0.0 {
99 return None;
100 }
101 Some(nearest)
102}
103
104pub fn safe_coerce_scalar(value: &ScalarValue, ty: &DataType) -> Option<ScalarValue> {
109 if let DataType::Dictionary(key_type, value_type) = ty {
115 if matches!(value, ScalarValue::Null) {
116 return Some(value.clone());
117 }
118 let inner = safe_coerce_scalar(value, value_type)?;
119 return Some(ScalarValue::Dictionary(key_type.clone(), Box::new(inner)));
120 }
121 match value {
122 ScalarValue::Int8(val) => match ty {
123 DataType::Int8 => Some(value.clone()),
124 DataType::Int16 => val.map(|v| ScalarValue::Int16(Some(i16::from(v)))),
125 DataType::Int32 => val.map(|v| ScalarValue::Int32(Some(i32::from(v)))),
126 DataType::Int64 => val.map(|v| ScalarValue::Int64(Some(i64::from(v)))),
127 DataType::UInt8 => {
128 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
129 }
130 DataType::UInt16 => {
131 val.and_then(|v| u16::try_from(v).map(|v| ScalarValue::UInt16(Some(v))).ok())
132 }
133 DataType::UInt32 => {
134 val.and_then(|v| u32::try_from(v).map(|v| ScalarValue::UInt32(Some(v))).ok())
135 }
136 DataType::UInt64 => {
137 val.and_then(|v| u64::try_from(v).map(|v| ScalarValue::UInt64(Some(v))).ok())
138 }
139 DataType::Float16 => {
140 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
141 }
142 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(f32::from(v)))),
143 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(f64::from(v)))),
144 _ => None,
145 },
146 ScalarValue::Int16(val) => match ty {
147 DataType::Int8 => {
148 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
149 }
150 DataType::Int16 => Some(value.clone()),
151 DataType::Int32 => val.map(|v| ScalarValue::Int32(Some(i32::from(v)))),
152 DataType::Int64 => val.map(|v| ScalarValue::Int64(Some(i64::from(v)))),
153 DataType::UInt8 => {
154 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
155 }
156 DataType::UInt16 => {
157 val.and_then(|v| u16::try_from(v).map(|v| ScalarValue::UInt16(Some(v))).ok())
158 }
159 DataType::UInt32 => {
160 val.and_then(|v| u32::try_from(v).map(|v| ScalarValue::UInt32(Some(v))).ok())
161 }
162 DataType::UInt64 => {
163 val.and_then(|v| u64::try_from(v).map(|v| ScalarValue::UInt64(Some(v))).ok())
164 }
165 DataType::Float16 => {
166 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
167 }
168 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(f32::from(v)))),
169 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(f64::from(v)))),
170 _ => None,
171 },
172 ScalarValue::Int32(val) => match ty {
173 DataType::Int8 => {
174 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
175 }
176 DataType::Int16 => {
177 val.and_then(|v| i16::try_from(v).map(|v| ScalarValue::Int16(Some(v))).ok())
178 }
179 DataType::Int32 => Some(value.clone()),
180 DataType::Int64 => val.map(|v| ScalarValue::Int64(Some(i64::from(v)))),
181 DataType::UInt8 => {
182 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
183 }
184 DataType::UInt16 => {
185 val.and_then(|v| u16::try_from(v).map(|v| ScalarValue::UInt16(Some(v))).ok())
186 }
187 DataType::UInt32 => {
188 val.and_then(|v| u32::try_from(v).map(|v| ScalarValue::UInt32(Some(v))).ok())
189 }
190 DataType::UInt64 => {
191 val.and_then(|v| u64::try_from(v).map(|v| ScalarValue::UInt64(Some(v))).ok())
192 }
193 DataType::Float16 => {
197 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
198 }
199 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(v as f32))),
200 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(v as f64))),
201 _ => None,
202 },
203 ScalarValue::Int64(val) => match ty {
204 DataType::Int8 => {
205 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
206 }
207 DataType::Int16 => {
208 val.and_then(|v| i16::try_from(v).map(|v| ScalarValue::Int16(Some(v))).ok())
209 }
210 DataType::Int32 => {
211 val.and_then(|v| i32::try_from(v).map(|v| ScalarValue::Int32(Some(v))).ok())
212 }
213 DataType::Int64 => Some(value.clone()),
214 DataType::UInt8 => {
215 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
216 }
217 DataType::UInt16 => {
218 val.and_then(|v| u16::try_from(v).map(|v| ScalarValue::UInt16(Some(v))).ok())
219 }
220 DataType::UInt32 => {
221 val.and_then(|v| u32::try_from(v).map(|v| ScalarValue::UInt32(Some(v))).ok())
222 }
223 DataType::UInt64 => {
224 val.and_then(|v| u64::try_from(v).map(|v| ScalarValue::UInt64(Some(v))).ok())
225 }
226 DataType::Float16 => {
228 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
229 }
230 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(v as f32))),
231 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(v as f64))),
232 DataType::Decimal128(_, _) | DataType::Decimal256(_, _) => value.cast_to(ty).ok(),
233 DataType::Time32(TimeUnit::Second) => val.and_then(|v| {
234 i32::try_from(v)
235 .ok()
236 .map(|v| ScalarValue::Time32Second(Some(v)))
237 }),
238 DataType::Time32(TimeUnit::Millisecond) => val.and_then(|v| {
239 i32::try_from(v)
240 .ok()
241 .map(|v| ScalarValue::Time32Millisecond(Some(v)))
242 }),
243 _ => None,
244 },
245 ScalarValue::UInt8(val) => match ty {
246 DataType::Int8 => {
247 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
248 }
249 DataType::Int16 => val.map(|v| ScalarValue::Int16(Some(v.into()))),
250 DataType::Int32 => val.map(|v| ScalarValue::Int32(Some(v.into()))),
251 DataType::Int64 => val.map(|v| ScalarValue::Int64(Some(v.into()))),
252 DataType::UInt8 => Some(value.clone()),
253 DataType::UInt16 => val.map(|v| ScalarValue::UInt16(Some(u16::from(v)))),
254 DataType::UInt32 => val.map(|v| ScalarValue::UInt32(Some(u32::from(v)))),
255 DataType::UInt64 => val.map(|v| ScalarValue::UInt64(Some(u64::from(v)))),
256 DataType::Float16 => {
257 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
258 }
259 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(f32::from(v)))),
260 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(f64::from(v)))),
261 _ => None,
262 },
263 ScalarValue::UInt16(val) => match ty {
264 DataType::Int8 => {
265 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
266 }
267 DataType::Int16 => {
268 val.and_then(|v| i16::try_from(v).map(|v| ScalarValue::Int16(Some(v))).ok())
269 }
270 DataType::Int32 => val.map(|v| ScalarValue::Int32(Some(v.into()))),
271 DataType::Int64 => val.map(|v| ScalarValue::Int64(Some(v.into()))),
272 DataType::UInt8 => {
273 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
274 }
275 DataType::UInt16 => Some(value.clone()),
276 DataType::UInt32 => val.map(|v| ScalarValue::UInt32(Some(u32::from(v)))),
277 DataType::UInt64 => val.map(|v| ScalarValue::UInt64(Some(u64::from(v)))),
278 DataType::Float16 => {
279 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
280 }
281 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(f32::from(v)))),
282 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(f64::from(v)))),
283 _ => None,
284 },
285 ScalarValue::UInt32(val) => match ty {
286 DataType::Int8 => {
287 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
288 }
289 DataType::Int16 => {
290 val.and_then(|v| i16::try_from(v).map(|v| ScalarValue::Int16(Some(v))).ok())
291 }
292 DataType::Int32 => {
293 val.and_then(|v| i32::try_from(v).map(|v| ScalarValue::Int32(Some(v))).ok())
294 }
295 DataType::Int64 => val.map(|v| ScalarValue::Int64(Some(v.into()))),
296 DataType::UInt8 => {
297 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
298 }
299 DataType::UInt16 => {
300 val.and_then(|v| u16::try_from(v).map(|v| ScalarValue::UInt16(Some(v))).ok())
301 }
302 DataType::UInt32 => Some(value.clone()),
303 DataType::UInt64 => val.map(|v| ScalarValue::UInt64(Some(u64::from(v)))),
304 DataType::Float16 => {
306 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
307 }
308 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(v as f32))),
309 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(v as f64))),
310 _ => None,
311 },
312 ScalarValue::UInt64(val) => match ty {
313 DataType::Int8 => {
314 val.and_then(|v| i8::try_from(v).map(|v| ScalarValue::Int8(Some(v))).ok())
315 }
316 DataType::Int16 => {
317 val.and_then(|v| i16::try_from(v).map(|v| ScalarValue::Int16(Some(v))).ok())
318 }
319 DataType::Int32 => {
320 val.and_then(|v| i32::try_from(v).map(|v| ScalarValue::Int32(Some(v))).ok())
321 }
322 DataType::Int64 => {
323 val.and_then(|v| i64::try_from(v).map(|v| ScalarValue::Int64(Some(v))).ok())
324 }
325 DataType::UInt8 => {
326 val.and_then(|v| u8::try_from(v).map(|v| ScalarValue::UInt8(Some(v))).ok())
327 }
328 DataType::UInt16 => {
329 val.and_then(|v| u16::try_from(v).map(|v| ScalarValue::UInt16(Some(v))).ok())
330 }
331 DataType::UInt32 => {
332 val.and_then(|v| u32::try_from(v).map(|v| ScalarValue::UInt32(Some(v))).ok())
333 }
334 DataType::UInt64 => Some(value.clone()),
335 DataType::Float16 => {
337 val.and_then(|v| coerce_to_f16(v as f64).map(|v| ScalarValue::Float16(Some(v))))
338 }
339 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(v as f32))),
340 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(v as f64))),
341 _ => None,
342 },
343 ScalarValue::Float16(val) => match ty {
344 DataType::Float16 => Some(value.clone()),
345 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(v.to_f32()))),
346 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(v.to_f64()))),
347 _ => None,
348 },
349 ScalarValue::Float32(val) => match ty {
350 DataType::Float16 => {
351 val.and_then(|v| coerce_to_f16(f64::from(v)).map(|v| ScalarValue::Float16(Some(v))))
352 }
353 DataType::Float32 => Some(value.clone()),
354 DataType::Float64 => val.map(|v| ScalarValue::Float64(Some(f64::from(v)))),
355 _ => None,
356 },
357 ScalarValue::Float64(val) => match ty {
358 DataType::Float16 => {
359 val.and_then(|v| coerce_to_f16(v).map(|v| ScalarValue::Float16(Some(v))))
360 }
361 DataType::Float32 => val.map(|v| ScalarValue::Float32(Some(v as f32))),
362 DataType::Float64 => Some(value.clone()),
363 _ => None,
364 },
365 ScalarValue::Utf8(val) => match ty {
366 DataType::Utf8 => Some(value.clone()),
367 DataType::LargeUtf8 => Some(ScalarValue::LargeUtf8(val.clone())),
368 DataType::Utf8View => Some(ScalarValue::Utf8View(val.clone())),
369 _ => None,
370 },
371 ScalarValue::LargeUtf8(val) => match ty {
372 DataType::Utf8 => Some(ScalarValue::Utf8(val.clone())),
373 DataType::LargeUtf8 => Some(value.clone()),
374 DataType::Utf8View => Some(ScalarValue::Utf8View(val.clone())),
375 _ => None,
376 },
377 ScalarValue::Utf8View(val) => match ty {
378 DataType::Utf8 => Some(ScalarValue::Utf8(val.clone())),
379 DataType::LargeUtf8 => Some(ScalarValue::LargeUtf8(val.clone())),
380 DataType::Utf8View => Some(value.clone()),
381 _ => None,
382 },
383 ScalarValue::Boolean(_) => match ty {
384 DataType::Boolean => Some(value.clone()),
385 _ => None,
386 },
387 ScalarValue::Null => Some(value.clone()),
388 ScalarValue::List(values) => {
389 let values = values.clone() as ArrayRef;
390 let new_values = cast(&values, ty).ok()?;
391 match ty {
392 DataType::List(_) => {
393 Some(ScalarValue::List(Arc::new(new_values.as_list().clone())))
394 }
395 DataType::LargeList(_) => Some(ScalarValue::LargeList(Arc::new(
396 new_values.as_list().clone(),
397 ))),
398 DataType::FixedSizeList(_, _) => Some(ScalarValue::FixedSizeList(Arc::new(
399 new_values.as_fixed_size_list().clone(),
400 ))),
401 _ => None,
402 }
403 }
404 ScalarValue::TimestampSecond(seconds, _) => match ty {
405 DataType::Timestamp(TimeUnit::Second, _) => Some(value.clone()),
406 DataType::Timestamp(TimeUnit::Millisecond, tz) => seconds
407 .and_then(|v| v.checked_mul(1000))
408 .map(|val| ScalarValue::TimestampMillisecond(Some(val), tz.clone())),
409 DataType::Timestamp(TimeUnit::Microsecond, tz) => seconds
410 .and_then(|v| v.checked_mul(1000000))
411 .map(|val| ScalarValue::TimestampMicrosecond(Some(val), tz.clone())),
412 DataType::Timestamp(TimeUnit::Nanosecond, tz) => seconds
413 .and_then(|v| v.checked_mul(1000000000))
414 .map(|val| ScalarValue::TimestampNanosecond(Some(val), tz.clone())),
415 _ => None,
416 },
417 ScalarValue::TimestampMillisecond(millis, _) => match ty {
418 DataType::Timestamp(TimeUnit::Second, tz) => {
419 millis.map(|val| ScalarValue::TimestampSecond(Some(val / 1000), tz.clone()))
420 }
421 DataType::Timestamp(TimeUnit::Millisecond, _) => Some(value.clone()),
422 DataType::Timestamp(TimeUnit::Microsecond, tz) => millis
423 .and_then(|v| v.checked_mul(1000))
424 .map(|val| ScalarValue::TimestampMicrosecond(Some(val), tz.clone())),
425 DataType::Timestamp(TimeUnit::Nanosecond, tz) => millis
426 .and_then(|v| v.checked_mul(1000000))
427 .map(|val| ScalarValue::TimestampNanosecond(Some(val), tz.clone())),
428 _ => None,
429 },
430 ScalarValue::TimestampMicrosecond(micros, _) => match ty {
431 DataType::Timestamp(TimeUnit::Second, tz) => {
432 micros.map(|val| ScalarValue::TimestampSecond(Some(val / 1000000), tz.clone()))
433 }
434 DataType::Timestamp(TimeUnit::Millisecond, tz) => {
435 micros.map(|val| ScalarValue::TimestampMillisecond(Some(val / 1000), tz.clone()))
436 }
437 DataType::Timestamp(TimeUnit::Microsecond, _) => Some(value.clone()),
438 DataType::Timestamp(TimeUnit::Nanosecond, tz) => micros
439 .and_then(|v| v.checked_mul(1000))
440 .map(|val| ScalarValue::TimestampNanosecond(Some(val), tz.clone())),
441 _ => None,
442 },
443 ScalarValue::TimestampNanosecond(nanos, _) => {
444 match ty {
445 DataType::Timestamp(TimeUnit::Second, tz) => nanos
446 .map(|val| ScalarValue::TimestampSecond(Some(val / 1000000000), tz.clone())),
447 DataType::Timestamp(TimeUnit::Millisecond, tz) => nanos
448 .map(|val| ScalarValue::TimestampMillisecond(Some(val / 1000000), tz.clone())),
449 DataType::Timestamp(TimeUnit::Microsecond, tz) => {
450 nanos.map(|val| ScalarValue::TimestampMicrosecond(Some(val / 1000), tz.clone()))
451 }
452 DataType::Timestamp(TimeUnit::Nanosecond, _) => Some(value.clone()),
453 _ => None,
454 }
455 }
456 ScalarValue::Date32(ticks) => match ty {
457 DataType::Date32 => Some(value.clone()),
458 DataType::Date64 => Some(ScalarValue::Date64(
459 ticks.map(|v| i64::from(v) * MS_PER_DAY),
460 )),
461 _ => None,
462 },
463 ScalarValue::Date64(ticks) => match ty {
464 DataType::Date32 => Some(ScalarValue::Date32(ticks.map(|v| (v / MS_PER_DAY) as i32))),
465 DataType::Date64 => Some(value.clone()),
466 _ => None,
467 },
468 ScalarValue::Time32Second(seconds) => {
469 match ty {
470 DataType::Time32(TimeUnit::Second) => Some(value.clone()),
471 DataType::Time32(TimeUnit::Millisecond) => {
472 seconds.map(|val| ScalarValue::Time32Millisecond(Some(val * 1000)))
473 }
474 DataType::Time64(TimeUnit::Microsecond) => seconds
475 .map(|val| ScalarValue::Time64Microsecond(Some(i64::from(val) * 1000000))),
476 DataType::Time64(TimeUnit::Nanosecond) => seconds
477 .map(|val| ScalarValue::Time64Nanosecond(Some(i64::from(val) * 1000000000))),
478 _ => None,
479 }
480 }
481 ScalarValue::Time32Millisecond(millis) => match ty {
482 DataType::Time32(TimeUnit::Second) => {
483 millis.map(|val| ScalarValue::Time32Second(Some(val / 1000)))
484 }
485 DataType::Time32(TimeUnit::Millisecond) => Some(value.clone()),
486 DataType::Time64(TimeUnit::Microsecond) => {
487 millis.map(|val| ScalarValue::Time64Microsecond(Some(i64::from(val) * 1000)))
488 }
489 DataType::Time64(TimeUnit::Nanosecond) => {
490 millis.map(|val| ScalarValue::Time64Nanosecond(Some(i64::from(val) * 1000000)))
491 }
492 _ => None,
493 },
494 ScalarValue::Time64Microsecond(micros) => match ty {
495 DataType::Time32(TimeUnit::Second) => {
496 micros.map(|val| ScalarValue::Time32Second(Some((val / 1000000) as i32)))
497 }
498 DataType::Time32(TimeUnit::Millisecond) => {
499 micros.map(|val| ScalarValue::Time32Millisecond(Some((val / 1000) as i32)))
500 }
501 DataType::Time64(TimeUnit::Microsecond) => Some(value.clone()),
502 DataType::Time64(TimeUnit::Nanosecond) => {
503 micros.map(|val| ScalarValue::Time64Nanosecond(Some(val * 1000)))
504 }
505 _ => None,
506 },
507 ScalarValue::Time64Nanosecond(nanos) => match ty {
508 DataType::Time32(TimeUnit::Second) => {
509 nanos.map(|val| ScalarValue::Time32Second(Some((val / 1000000000) as i32)))
510 }
511 DataType::Time32(TimeUnit::Millisecond) => {
512 nanos.map(|val| ScalarValue::Time32Millisecond(Some((val / 1000000) as i32)))
513 }
514 DataType::Time64(TimeUnit::Microsecond) => {
515 nanos.map(|val| ScalarValue::Time64Microsecond(Some(val / 1000)))
516 }
517 DataType::Time64(TimeUnit::Nanosecond) => Some(value.clone()),
518 _ => None,
519 },
520 ScalarValue::LargeList(values) => {
521 let values = values.clone() as ArrayRef;
522 let new_values = cast(&values, ty).ok()?;
523 match ty {
524 DataType::List(_) => {
525 Some(ScalarValue::List(Arc::new(new_values.as_list().clone())))
526 }
527 DataType::LargeList(_) => Some(ScalarValue::LargeList(Arc::new(
528 new_values.as_list().clone(),
529 ))),
530 DataType::FixedSizeList(_, _) => Some(ScalarValue::FixedSizeList(Arc::new(
531 new_values.as_fixed_size_list().clone(),
532 ))),
533 _ => None,
534 }
535 }
536 ScalarValue::FixedSizeList(values) => {
537 let values = values.clone() as ArrayRef;
538 let new_values = cast(&values, ty).ok()?;
539 match ty {
540 DataType::List(_) => {
541 Some(ScalarValue::List(Arc::new(new_values.as_list().clone())))
542 }
543 DataType::LargeList(_) => Some(ScalarValue::LargeList(Arc::new(
544 new_values.as_list().clone(),
545 ))),
546 DataType::FixedSizeList(_, _) => Some(ScalarValue::FixedSizeList(Arc::new(
547 new_values.as_fixed_size_list().clone(),
548 ))),
549 _ => None,
550 }
551 }
552 ScalarValue::FixedSizeBinary(len, value) => match ty {
553 DataType::FixedSizeBinary(len2) => {
554 if len == len2 {
555 Some(ScalarValue::FixedSizeBinary(*len, value.clone()))
556 } else {
557 None
558 }
559 }
560 DataType::Binary => Some(ScalarValue::Binary(value.clone())),
561 _ => None,
562 },
563 ScalarValue::Binary(value) => match ty {
564 DataType::Binary => Some(ScalarValue::Binary(value.clone())),
565 DataType::LargeBinary => Some(ScalarValue::LargeBinary(value.clone())),
566 DataType::BinaryView => Some(ScalarValue::BinaryView(value.clone())),
567 DataType::FixedSizeBinary(len) => {
568 if let Some(value) = value {
569 if value.len() == *len as usize {
570 Some(ScalarValue::FixedSizeBinary(*len, Some(value.clone())))
571 } else {
572 None
573 }
574 } else {
575 None
576 }
577 }
578 _ => None,
579 },
580 ScalarValue::BinaryView(val) => match ty {
581 DataType::Binary => Some(ScalarValue::Binary(val.clone())),
582 DataType::LargeBinary => Some(ScalarValue::LargeBinary(val.clone())),
583 DataType::BinaryView => Some(value.clone()),
584 _ => None,
585 },
586 ScalarValue::LargeBinary(_) => match ty {
587 DataType::LargeBinary => Some(value.clone()),
588 _ => None,
589 },
590 ScalarValue::Decimal128(_, _, _) => match ty {
591 DataType::Decimal128(_, _) => value.cast_to(ty).ok(),
592 _ => None,
593 },
594 ScalarValue::Decimal256(_, _, _) => match ty {
595 DataType::Decimal256(_, _) => value.cast_to(ty).ok(),
596 _ => None,
597 },
598 ScalarValue::DurationSecond(_)
599 | ScalarValue::DurationMillisecond(_)
600 | ScalarValue::DurationMicrosecond(_)
601 | ScalarValue::DurationNanosecond(_) => match ty {
602 DataType::Duration(_) => value.cast_to(ty).ok(),
603 _ => None,
604 },
605 ScalarValue::Dictionary(_, inner) => safe_coerce_scalar(inner, ty),
608 _ => None,
609 }
610}
611
612#[cfg(test)]
613mod tests {
614 use arrow::datatypes::i256;
615
616 use super::*;
617
618 #[test]
619 fn test_temporal_coerce() {
620 assert_eq!(
621 safe_coerce_scalar(
622 &ScalarValue::Int64(Some(5)),
623 &DataType::Time32(TimeUnit::Second),
624 ),
625 Some(ScalarValue::Time32Second(Some(5)))
626 );
627 assert_eq!(
628 safe_coerce_scalar(
629 &ScalarValue::Int64(Some(5000)),
630 &DataType::Time32(TimeUnit::Millisecond),
631 ),
632 Some(ScalarValue::Time32Millisecond(Some(5000)))
633 );
634 assert_eq!(
635 safe_coerce_scalar(
636 &ScalarValue::Int64(Some(i64::MAX)),
637 &DataType::Time32(TimeUnit::Second),
638 ),
639 None
640 );
641
642 assert_eq!(
645 safe_coerce_scalar(
646 &ScalarValue::TimestampSecond(Some(5), None),
647 &DataType::Timestamp(TimeUnit::Second, None),
648 ),
649 Some(ScalarValue::TimestampSecond(Some(5), None))
650 );
651 assert_eq!(
653 safe_coerce_scalar(
654 &ScalarValue::TimestampSecond(Some(5), None),
655 &DataType::Timestamp(TimeUnit::Millisecond, None),
656 ),
657 Some(ScalarValue::TimestampMillisecond(Some(5000), None))
658 );
659 assert_eq!(
661 safe_coerce_scalar(
662 &ScalarValue::TimestampSecond(Some(5), None),
663 &DataType::Timestamp(TimeUnit::Microsecond, None),
664 ),
665 Some(ScalarValue::TimestampMicrosecond(Some(5000000), None))
666 );
667 assert_eq!(
669 safe_coerce_scalar(
670 &ScalarValue::TimestampSecond(Some(5), None),
671 &DataType::Timestamp(TimeUnit::Nanosecond, None),
672 ),
673 Some(ScalarValue::TimestampNanosecond(Some(5000000000), None))
674 );
675 assert_eq!(
677 safe_coerce_scalar(
678 &ScalarValue::TimestampMillisecond(Some(5000), None),
679 &DataType::Timestamp(TimeUnit::Second, None),
680 ),
681 Some(ScalarValue::TimestampSecond(Some(5), None))
682 );
683 assert_eq!(
685 safe_coerce_scalar(
686 &ScalarValue::TimestampMillisecond(Some(5000), None),
687 &DataType::Timestamp(TimeUnit::Millisecond, None),
688 ),
689 Some(ScalarValue::TimestampMillisecond(Some(5000), None))
690 );
691 assert_eq!(
693 safe_coerce_scalar(
694 &ScalarValue::TimestampMillisecond(Some(5000), None),
695 &DataType::Timestamp(TimeUnit::Microsecond, None),
696 ),
697 Some(ScalarValue::TimestampMicrosecond(Some(5000000), None))
698 );
699 assert_eq!(
701 safe_coerce_scalar(
702 &ScalarValue::TimestampMillisecond(Some(5000), None),
703 &DataType::Timestamp(TimeUnit::Nanosecond, None),
704 ),
705 Some(ScalarValue::TimestampNanosecond(Some(5000000000), None))
706 );
707 assert_eq!(
709 safe_coerce_scalar(
710 &ScalarValue::TimestampMicrosecond(Some(5000000), None),
711 &DataType::Timestamp(TimeUnit::Second, None),
712 ),
713 Some(ScalarValue::TimestampSecond(Some(5), None))
714 );
715 assert_eq!(
717 safe_coerce_scalar(
718 &ScalarValue::TimestampMicrosecond(Some(5000000), None),
719 &DataType::Timestamp(TimeUnit::Millisecond, None),
720 ),
721 Some(ScalarValue::TimestampMillisecond(Some(5000), None))
722 );
723 assert_eq!(
725 safe_coerce_scalar(
726 &ScalarValue::TimestampMicrosecond(Some(5000000), None),
727 &DataType::Timestamp(TimeUnit::Microsecond, None),
728 ),
729 Some(ScalarValue::TimestampMicrosecond(Some(5000000), None))
730 );
731 assert_eq!(
733 safe_coerce_scalar(
734 &ScalarValue::TimestampMicrosecond(Some(5000000), None),
735 &DataType::Timestamp(TimeUnit::Nanosecond, None),
736 ),
737 Some(ScalarValue::TimestampNanosecond(Some(5000000000), None))
738 );
739 assert_eq!(
741 safe_coerce_scalar(
742 &ScalarValue::TimestampNanosecond(Some(5000000000), None),
743 &DataType::Timestamp(TimeUnit::Second, None),
744 ),
745 Some(ScalarValue::TimestampSecond(Some(5), None))
746 );
747 assert_eq!(
749 safe_coerce_scalar(
750 &ScalarValue::TimestampNanosecond(Some(5000000000), None),
751 &DataType::Timestamp(TimeUnit::Millisecond, None),
752 ),
753 Some(ScalarValue::TimestampMillisecond(Some(5000), None))
754 );
755 assert_eq!(
757 safe_coerce_scalar(
758 &ScalarValue::TimestampNanosecond(Some(5000000000), None),
759 &DataType::Timestamp(TimeUnit::Microsecond, None),
760 ),
761 Some(ScalarValue::TimestampMicrosecond(Some(5000000), None))
762 );
763 assert_eq!(
765 safe_coerce_scalar(
766 &ScalarValue::TimestampNanosecond(Some(5000000000), None),
767 &DataType::Timestamp(TimeUnit::Nanosecond, None),
768 ),
769 Some(ScalarValue::TimestampNanosecond(Some(5000000000), None))
770 );
771 assert_eq!(
774 safe_coerce_scalar(
775 &ScalarValue::TimestampNanosecond(Some(5987654321), None),
776 &DataType::Timestamp(TimeUnit::Second, None),
777 ),
778 Some(ScalarValue::TimestampSecond(Some(5), None))
779 );
780 assert_eq!(
782 safe_coerce_scalar(&ScalarValue::Date32(Some(5)), &DataType::Date32,),
783 Some(ScalarValue::Date32(Some(5)))
784 );
785 assert_eq!(
786 safe_coerce_scalar(&ScalarValue::Date32(Some(5)), &DataType::Date64,),
787 Some(ScalarValue::Date64(Some(5 * MS_PER_DAY)))
788 );
789 assert_eq!(
790 safe_coerce_scalar(
791 &ScalarValue::Date64(Some(5 * MS_PER_DAY)),
792 &DataType::Date32,
793 ),
794 Some(ScalarValue::Date32(Some(5)))
795 );
796 assert_eq!(
797 safe_coerce_scalar(&ScalarValue::Date64(Some(5)), &DataType::Date64,),
798 Some(ScalarValue::Date64(Some(5)))
799 );
800 assert_eq!(
802 safe_coerce_scalar(
803 &ScalarValue::Time32Second(Some(5)),
804 &DataType::Time32(TimeUnit::Second),
805 ),
806 Some(ScalarValue::Time32Second(Some(5)))
807 );
808 assert_eq!(
809 safe_coerce_scalar(
810 &ScalarValue::Time32Second(Some(5)),
811 &DataType::Time32(TimeUnit::Millisecond),
812 ),
813 Some(ScalarValue::Time32Millisecond(Some(5000)))
814 );
815 assert_eq!(
816 safe_coerce_scalar(
817 &ScalarValue::Time32Second(Some(5)),
818 &DataType::Time64(TimeUnit::Microsecond),
819 ),
820 Some(ScalarValue::Time64Microsecond(Some(5000000)))
821 );
822 assert_eq!(
823 safe_coerce_scalar(
824 &ScalarValue::Time32Second(Some(5)),
825 &DataType::Time64(TimeUnit::Nanosecond),
826 ),
827 Some(ScalarValue::Time64Nanosecond(Some(5000000000)))
828 );
829 assert_eq!(
830 safe_coerce_scalar(
831 &ScalarValue::Time32Millisecond(Some(5000)),
832 &DataType::Time32(TimeUnit::Second),
833 ),
834 Some(ScalarValue::Time32Second(Some(5)))
835 );
836 assert_eq!(
837 safe_coerce_scalar(
838 &ScalarValue::Time32Millisecond(Some(5000)),
839 &DataType::Time32(TimeUnit::Millisecond),
840 ),
841 Some(ScalarValue::Time32Millisecond(Some(5000)))
842 );
843 assert_eq!(
844 safe_coerce_scalar(
845 &ScalarValue::Time32Millisecond(Some(5000)),
846 &DataType::Time64(TimeUnit::Microsecond),
847 ),
848 Some(ScalarValue::Time64Microsecond(Some(5000000)))
849 );
850 assert_eq!(
851 safe_coerce_scalar(
852 &ScalarValue::Time32Millisecond(Some(5000)),
853 &DataType::Time64(TimeUnit::Nanosecond),
854 ),
855 Some(ScalarValue::Time64Nanosecond(Some(5000000000)))
856 );
857 assert_eq!(
858 safe_coerce_scalar(
859 &ScalarValue::Time64Microsecond(Some(5000000)),
860 &DataType::Time32(TimeUnit::Second),
861 ),
862 Some(ScalarValue::Time32Second(Some(5)))
863 );
864 assert_eq!(
865 safe_coerce_scalar(
866 &ScalarValue::Time64Microsecond(Some(5000000)),
867 &DataType::Time32(TimeUnit::Millisecond),
868 ),
869 Some(ScalarValue::Time32Millisecond(Some(5000)))
870 );
871 assert_eq!(
872 safe_coerce_scalar(
873 &ScalarValue::Time64Microsecond(Some(5000000)),
874 &DataType::Time64(TimeUnit::Microsecond),
875 ),
876 Some(ScalarValue::Time64Microsecond(Some(5000000)))
877 );
878 assert_eq!(
879 safe_coerce_scalar(
880 &ScalarValue::Time64Microsecond(Some(5000000)),
881 &DataType::Time64(TimeUnit::Nanosecond),
882 ),
883 Some(ScalarValue::Time64Nanosecond(Some(5000000000)))
884 );
885 assert_eq!(
886 safe_coerce_scalar(
887 &ScalarValue::Time64Nanosecond(Some(5000000000)),
888 &DataType::Time32(TimeUnit::Second),
889 ),
890 Some(ScalarValue::Time32Second(Some(5)))
891 );
892 assert_eq!(
893 safe_coerce_scalar(
894 &ScalarValue::Time64Nanosecond(Some(5000000000)),
895 &DataType::Time32(TimeUnit::Millisecond),
896 ),
897 Some(ScalarValue::Time32Millisecond(Some(5000)))
898 );
899 assert_eq!(
900 safe_coerce_scalar(
901 &ScalarValue::Time64Nanosecond(Some(5000000000)),
902 &DataType::Time64(TimeUnit::Microsecond),
903 ),
904 Some(ScalarValue::Time64Microsecond(Some(5000000)))
905 );
906 assert_eq!(
907 safe_coerce_scalar(
908 &ScalarValue::Time64Nanosecond(Some(5000000000)),
909 &DataType::Time64(TimeUnit::Nanosecond),
910 ),
911 Some(ScalarValue::Time64Nanosecond(Some(5000000000)))
912 );
913 assert_eq!(
914 safe_coerce_scalar(
915 &ScalarValue::DurationNanosecond(Some(2_000_000)),
916 &DataType::Duration(TimeUnit::Millisecond),
917 ),
918 Some(ScalarValue::DurationMillisecond(Some(2)))
919 );
920 }
921
922 #[test]
923 fn test_string_view_coerce() {
924 assert_eq!(
926 safe_coerce_scalar(&ScalarValue::Utf8(Some("hi".into())), &DataType::Utf8View),
927 Some(ScalarValue::Utf8View(Some("hi".into())))
928 );
929 assert_eq!(
930 safe_coerce_scalar(&ScalarValue::Utf8View(Some("hi".into())), &DataType::Utf8),
931 Some(ScalarValue::Utf8(Some("hi".into())))
932 );
933 assert_eq!(
934 safe_coerce_scalar(
935 &ScalarValue::Utf8View(Some("hi".into())),
936 &DataType::LargeUtf8
937 ),
938 Some(ScalarValue::LargeUtf8(Some("hi".into())))
939 );
940 assert_eq!(
941 safe_coerce_scalar(
942 &ScalarValue::LargeUtf8(Some("hi".into())),
943 &DataType::Utf8View
944 ),
945 Some(ScalarValue::Utf8View(Some("hi".into())))
946 );
947 assert_eq!(
949 safe_coerce_scalar(
950 &ScalarValue::Utf8View(Some("hi".into())),
951 &DataType::Utf8View
952 ),
953 Some(ScalarValue::Utf8View(Some("hi".into())))
954 );
955 assert_eq!(
957 safe_coerce_scalar(
958 &ScalarValue::Binary(Some(vec![1, 2, 3])),
959 &DataType::BinaryView
960 ),
961 Some(ScalarValue::BinaryView(Some(vec![1, 2, 3])))
962 );
963 assert_eq!(
964 safe_coerce_scalar(
965 &ScalarValue::BinaryView(Some(vec![1, 2, 3])),
966 &DataType::Binary
967 ),
968 Some(ScalarValue::Binary(Some(vec![1, 2, 3])))
969 );
970 assert_eq!(
971 safe_coerce_scalar(
972 &ScalarValue::BinaryView(Some(vec![1, 2, 3])),
973 &DataType::BinaryView
974 ),
975 Some(ScalarValue::BinaryView(Some(vec![1, 2, 3])))
976 );
977 assert_eq!(
978 safe_coerce_scalar(
979 &ScalarValue::LargeBinary(Some(vec![1, 2, 3])),
980 &DataType::LargeBinary
981 ),
982 Some(ScalarValue::LargeBinary(Some(vec![1, 2, 3])))
983 );
984 }
985
986 #[rstest::rstest]
991 #[case::int8(ScalarValue::Int8(Some(-2)))]
992 #[case::int16(ScalarValue::Int16(Some(-2)))]
993 #[case::int32(ScalarValue::Int32(Some(-2)))]
994 #[case::int64(ScalarValue::Int64(Some(-2)))]
995 #[case::float32(ScalarValue::Float32(Some(-2.0)))]
996 #[case::float64(ScalarValue::Float64(Some(-2.0)))]
997 #[case::float16(ScalarValue::Float16(Some(f16::from_f32(-2.0))))]
998 fn numeric_literals_coerce_to_f16(#[case] value: ScalarValue) {
999 assert_eq!(
1000 safe_coerce_scalar(&value, &DataType::Float16),
1001 Some(ScalarValue::Float16(Some(f16::from_f32(-2.0)))),
1002 );
1003 }
1004
1005 #[rstest::rstest]
1006 #[case::uint8(ScalarValue::UInt8(Some(2)))]
1007 #[case::uint16(ScalarValue::UInt16(Some(2)))]
1008 #[case::uint32(ScalarValue::UInt32(Some(2)))]
1009 #[case::uint64(ScalarValue::UInt64(Some(2)))]
1010 fn unsigned_literals_coerce_to_f16(#[case] value: ScalarValue) {
1011 assert_eq!(
1012 safe_coerce_scalar(&value, &DataType::Float16),
1013 Some(ScalarValue::Float16(Some(f16::from_f32(2.0)))),
1014 );
1015 }
1016
1017 #[test]
1020 fn test_f16_literal_widens() {
1021 let half = ScalarValue::Float16(Some(f16::from_f32(0.5)));
1022 assert_eq!(
1023 safe_coerce_scalar(&half, &DataType::Float32),
1024 Some(ScalarValue::Float32(Some(0.5))),
1025 );
1026 assert_eq!(
1027 safe_coerce_scalar(&half, &DataType::Float64),
1028 Some(ScalarValue::Float64(Some(0.5))),
1029 );
1030 assert_eq!(safe_coerce_scalar(&half, &DataType::Int32), None);
1031 }
1032
1033 #[rstest::rstest]
1038 #[case::rounds(0.1, Some(0x2E66))]
1040 #[case::odd_integer_ties_down(2049.0, Some(0x6800))]
1044 #[case::just_above_a_tie(2049.001, Some(0x6801))]
1048 #[case::largest_finite(65504.0, Some(0x7BFF))]
1049 #[case::just_under_overflow(65519.0, Some(0x7BFF))]
1051 #[case::smallest_subnormal(6e-8, Some(0x0001))]
1052 #[case::overflow_threshold(65520.0, None)]
1054 #[case::overflow(70000.0, None)]
1055 #[case::negative_overflow(-70000.0, None)]
1056 #[case::f32_max(f32::MAX as f64, None)]
1057 #[case::underflow(1e-30, None)]
1059 #[case::negative_underflow(-1e-30, None)]
1060 fn test_f16_range_edges(#[case] input: f64, #[case] expected: Option<u16>) {
1061 let coerced = safe_coerce_scalar(&ScalarValue::Float64(Some(input)), &DataType::Float16);
1062 match expected {
1063 Some(bits) => assert_eq!(
1064 coerced,
1065 Some(ScalarValue::Float16(Some(f16::from_bits(bits)))),
1066 ),
1067 None => assert_eq!(coerced, None),
1068 }
1069 }
1070
1071 #[test]
1074 fn test_f16_keeps_non_finite_literals() {
1075 for (input, expected) in [
1076 (f64::INFINITY, f16::INFINITY),
1077 (f64::NEG_INFINITY, f16::NEG_INFINITY),
1078 ] {
1079 assert_eq!(
1080 safe_coerce_scalar(&ScalarValue::Float64(Some(input)), &DataType::Float16),
1081 Some(ScalarValue::Float16(Some(expected))),
1082 );
1083 }
1084 let nan = safe_coerce_scalar(&ScalarValue::Float64(Some(f64::NAN)), &DataType::Float16);
1085 assert!(matches!(nan, Some(ScalarValue::Float16(Some(v))) if v.is_nan()));
1086 }
1087
1088 #[test]
1091 fn test_f16_keeps_zero_sign() {
1092 assert_eq!(
1093 safe_coerce_scalar(&ScalarValue::Float64(Some(-0.0)), &DataType::Float16),
1094 Some(ScalarValue::Float16(Some(f16::NEG_ZERO))),
1095 );
1096 assert_eq!(
1097 safe_coerce_scalar(&ScalarValue::Float64(Some(0.0)), &DataType::Float16),
1098 Some(ScalarValue::Float16(Some(f16::ZERO))),
1099 );
1100 assert_eq!(
1101 safe_coerce_scalar(&ScalarValue::Int64(Some(0)), &DataType::Float16),
1102 Some(ScalarValue::Float16(Some(f16::ZERO))),
1103 );
1104 }
1105
1106 #[test]
1115 fn test_f16_rounds_to_nearest_even_across_the_whole_range() {
1116 fn coerce(value: f64) -> Option<f16> {
1117 match safe_coerce_scalar(&ScalarValue::Float64(Some(value)), &DataType::Float16) {
1118 Some(ScalarValue::Float16(Some(v))) => Some(v),
1119 None => None,
1121 other => panic!("expected a Float16 literal for {value}, got {other:?}"),
1122 }
1123 }
1124 fn want(expected: f16, input: f64) -> Option<f16> {
1127 if expected == f16::ZERO && input != 0.0 {
1128 None
1129 } else {
1130 Some(expected)
1131 }
1132 }
1133
1134 for lower_bits in 0..0x7BFFu16 {
1138 let lower = f16::from_bits(lower_bits);
1139 let upper = f16::from_bits(lower_bits + 1);
1140 let midpoint = (lower.to_f64() + upper.to_f64()) / 2.0;
1142 let below = f64::from_bits(midpoint.to_bits() - 1);
1143 let above = f64::from_bits(midpoint.to_bits() + 1);
1144
1145 assert_eq!(coerce(below), want(lower, below), "just below {midpoint}");
1146 assert_eq!(coerce(above), want(upper, above), "just above {midpoint}");
1147 let even = if lower.to_bits() & 1 == 0 {
1148 lower
1149 } else {
1150 upper
1151 };
1152 assert_eq!(coerce(midpoint), want(even, midpoint), "at {midpoint}");
1153 }
1154 }
1155
1156 #[rstest::rstest]
1159 #[case(0.1)]
1160 #[case(2049.001)]
1161 #[case(65504.0)]
1162 #[case(6e-8)]
1163 #[case(70000.0)]
1164 #[case(1e-30)]
1165 fn test_f16_coercion_is_sign_symmetric(#[case] magnitude: f64) {
1166 let positive =
1167 safe_coerce_scalar(&ScalarValue::Float64(Some(magnitude)), &DataType::Float16);
1168 let negative =
1169 safe_coerce_scalar(&ScalarValue::Float64(Some(-magnitude)), &DataType::Float16);
1170 let flipped = match positive {
1171 Some(ScalarValue::Float16(Some(v))) => Some(ScalarValue::Float16(Some(-v))),
1172 other => other,
1173 };
1174 assert_eq!(negative, flipped);
1175 }
1176
1177 #[test]
1178 fn test_decimal_coerce() {
1179 assert_eq!(
1180 safe_coerce_scalar(
1181 &ScalarValue::Decimal128(Some(2), 10, 0),
1182 &DataType::Decimal128(12, 2),
1183 ),
1184 Some(ScalarValue::Decimal128(Some(200), 12, 2))
1185 );
1186 assert_eq!(
1187 safe_coerce_scalar(
1188 &ScalarValue::Decimal256(Some(i256::from_i128(2)), 76, 0),
1189 &DataType::Decimal256(76, 2),
1190 ),
1191 Some(ScalarValue::Decimal256(Some(i256::from_i128(200)), 76, 2))
1192 );
1193 }
1194
1195 #[test]
1196 fn test_dictionary_coerce() {
1197 let dict_ty = DataType::Dictionary(Box::new(DataType::Int16), Box::new(DataType::Utf8));
1198
1199 assert_eq!(
1202 safe_coerce_scalar(&ScalarValue::Utf8(Some("com".to_string())), &dict_ty),
1203 Some(ScalarValue::Dictionary(
1204 Box::new(DataType::Int16),
1205 Box::new(ScalarValue::Utf8(Some("com".to_string()))),
1206 ))
1207 );
1208
1209 assert_eq!(
1212 safe_coerce_scalar(&ScalarValue::LargeUtf8(Some("com".to_string())), &dict_ty),
1213 Some(ScalarValue::Dictionary(
1214 Box::new(DataType::Int16),
1215 Box::new(ScalarValue::Utf8(Some("com".to_string()))),
1216 ))
1217 );
1218
1219 assert_eq!(
1221 safe_coerce_scalar(
1222 &ScalarValue::Dictionary(
1223 Box::new(DataType::Int16),
1224 Box::new(ScalarValue::Utf8(Some("com".to_string()))),
1225 ),
1226 &DataType::Utf8,
1227 ),
1228 Some(ScalarValue::Utf8(Some("com".to_string())))
1229 );
1230
1231 assert_eq!(
1234 safe_coerce_scalar(
1235 &ScalarValue::Dictionary(
1236 Box::new(DataType::Int32),
1237 Box::new(ScalarValue::Utf8(Some("com".to_string()))),
1238 ),
1239 &dict_ty,
1240 ),
1241 Some(ScalarValue::Dictionary(
1242 Box::new(DataType::Int16),
1243 Box::new(ScalarValue::Utf8(Some("com".to_string()))),
1244 ))
1245 );
1246
1247 assert_eq!(
1250 safe_coerce_scalar(&ScalarValue::Null, &dict_ty),
1251 Some(ScalarValue::Null)
1252 );
1253
1254 assert_eq!(
1261 safe_coerce_scalar(&ScalarValue::Utf8(None), &dict_ty),
1262 Some(ScalarValue::Dictionary(
1263 Box::new(DataType::Int16),
1264 Box::new(ScalarValue::Utf8(None)),
1265 ))
1266 );
1267
1268 assert_eq!(
1271 safe_coerce_scalar(&ScalarValue::LargeUtf8(None), &dict_ty),
1272 Some(ScalarValue::Dictionary(
1273 Box::new(DataType::Int16),
1274 Box::new(ScalarValue::Utf8(None)),
1275 ))
1276 );
1277
1278 assert_eq!(
1280 safe_coerce_scalar(
1281 &ScalarValue::Utf8(Some("com".to_string())),
1282 &DataType::Dictionary(Box::new(DataType::Int16), Box::new(DataType::Int32)),
1283 ),
1284 None
1285 );
1286 }
1287}