|
1 | 1 | use std::sync::Arc; |
2 | 2 |
|
3 | 3 | use vortex_dtype::{DType, ExtDType}; |
4 | | -use vortex_error::{vortex_bail, vortex_panic, VortexError, VortexResult}; |
| 4 | +use vortex_error::{vortex_bail, VortexError, VortexResult}; |
5 | 5 |
|
6 | 6 | use crate::value::ScalarValue; |
7 | 7 | use crate::Scalar; |
8 | 8 |
|
9 | 9 | pub struct ExtScalar<'a> { |
10 | | - dtype: &'a DType, |
| 10 | + ext_dtype: &'a ExtDType, |
11 | 11 | value: &'a ScalarValue, |
12 | 12 | } |
13 | 13 |
|
14 | 14 | impl<'a> ExtScalar<'a> { |
15 | 15 | pub fn try_new(dtype: &'a DType, value: &'a ScalarValue) -> VortexResult<Self> { |
16 | | - if !matches!(dtype, DType::Extension(..)) { |
| 16 | + let DType::Extension(ext_dtype) = dtype else { |
17 | 17 | vortex_bail!("Expected extension scalar, found {}", dtype) |
18 | | - } |
19 | | - |
20 | | - Ok(Self { dtype, value }) |
21 | | - } |
| 18 | + }; |
22 | 19 |
|
23 | | - #[inline] |
24 | | - pub fn dtype(&self) -> &'a DType { |
25 | | - self.dtype |
| 20 | + Ok(Self { ext_dtype, value }) |
26 | 21 | } |
27 | 22 |
|
28 | 23 | /// Returns the storage scalar of the extension scalar. |
29 | 24 | pub fn storage(&self) -> Scalar { |
30 | | - let storage_dtype = if let DType::Extension(ext_dtype) = self.dtype() { |
31 | | - ext_dtype.storage_dtype().clone() |
32 | | - } else { |
33 | | - vortex_panic!("Expected extension DType: {}", self.dtype()); |
34 | | - }; |
35 | | - Scalar::new(storage_dtype, self.value.clone()) |
| 25 | + Scalar::new(self.ext_dtype.storage_dtype().clone(), self.value.clone()) |
36 | 26 | } |
37 | 27 |
|
38 | | - pub fn cast(&self, _dtype: &DType) -> VortexResult<Scalar> { |
39 | | - todo!() |
| 28 | + pub(crate) fn cast(&self, dtype: &DType) -> VortexResult<Scalar> { |
| 29 | + if self.value.is_null() && !dtype.is_nullable() { |
| 30 | + vortex_bail!( |
| 31 | + "cannot cast extension dtype with id {} and storage type {} to {}", |
| 32 | + self.ext_dtype.id(), |
| 33 | + self.ext_dtype.storage_dtype(), |
| 34 | + dtype |
| 35 | + ); |
| 36 | + } |
| 37 | + |
| 38 | + if self.ext_dtype.storage_dtype().eq_ignore_nullability(dtype) { |
| 39 | + // Casting from an extension type to the underlying storage type is OK. |
| 40 | + return Ok(Scalar::new(dtype.clone(), self.value.clone())); |
| 41 | + } |
| 42 | + |
| 43 | + if let DType::Extension(ext_dtype) = dtype { |
| 44 | + if self.ext_dtype.eq_ignore_nullability(ext_dtype) { |
| 45 | + return Ok(Scalar::new(dtype.clone(), self.value.clone())); |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + vortex_bail!( |
| 50 | + "cannot cast extension dtype with id {} and storage type {} to {}", |
| 51 | + self.ext_dtype.id(), |
| 52 | + self.ext_dtype.storage_dtype(), |
| 53 | + dtype |
| 54 | + ); |
40 | 55 | } |
41 | 56 | } |
42 | 57 |
|
|
0 commit comments