1use std::sync::Arc;
7
8use vortex_buffer::BufferString;
9use vortex_buffer::ByteBuffer;
10use vortex_error::VortexExpect;
11use vortex_error::VortexResult;
12use vortex_error::vortex_bail;
13use vortex_error::vortex_ensure_eq;
14use vortex_error::vortex_err;
15use vortex_error::vortex_panic;
16
17use crate::dtype::DType;
18use crate::dtype::DecimalDType;
19use crate::dtype::NativePType;
20use crate::dtype::Nullability;
21use crate::dtype::PType;
22use crate::dtype::UnionVariants;
23use crate::dtype::extension::ExtDType;
24use crate::dtype::extension::ExtDTypeRef;
25use crate::dtype::extension::ExtVTable;
26use crate::scalar::DecimalValue;
27use crate::scalar::PValue;
28use crate::scalar::Scalar;
29use crate::scalar::ScalarValue;
30use crate::scalar::UnionValue;
31
32impl Scalar {
34 pub fn bool(value: bool, nullability: Nullability) -> Self {
36 Self::try_new(DType::Bool(nullability), Some(ScalarValue::Bool(value)))
37 .vortex_expect("unable to construct a boolean `Scalar`")
38 }
39
40 pub fn primitive<T: NativePType + Into<PValue>>(value: T, nullability: Nullability) -> Self {
42 Self::primitive_value(value.into(), T::PTYPE, nullability)
43 }
44
45 pub fn primitive_value(value: PValue, ptype: PType, nullability: Nullability) -> Self {
50 Self::try_new(
51 DType::Primitive(ptype, nullability),
52 Some(ScalarValue::Primitive(value)),
53 )
54 .vortex_expect("unable to construct a primitive `Scalar`")
55 }
56
57 pub fn decimal(
59 value: DecimalValue,
60 decimal_type: DecimalDType,
61 nullability: Nullability,
62 ) -> Self {
63 Self::try_new(
64 DType::Decimal(decimal_type, nullability),
65 Some(ScalarValue::Decimal(value)),
66 )
67 .vortex_expect("unable to construct a decimal `Scalar`")
68 }
69
70 pub fn utf8<B>(str: B, nullability: Nullability) -> Self
76 where
77 B: Into<BufferString>,
78 {
79 Self::try_utf8(str, nullability).unwrap()
80 }
81
82 pub fn try_utf8<B>(
88 str: B,
89 nullability: Nullability,
90 ) -> Result<Self, <B as TryInto<BufferString>>::Error>
91 where
92 B: TryInto<BufferString>,
93 {
94 Ok(Self::try_new(
95 DType::Utf8(nullability),
96 Some(ScalarValue::Utf8(str.try_into()?)),
97 )
98 .vortex_expect("unable to construct a UTF-8 `Scalar`"))
99 }
100
101 pub fn binary(buffer: impl Into<ByteBuffer>, nullability: Nullability) -> Self {
103 Self::try_new(
104 DType::Binary(nullability),
105 Some(ScalarValue::Binary(buffer.into())),
106 )
107 .vortex_expect("unable to construct a binary `Scalar`")
108 }
109
110 pub fn list(
117 element_dtype: impl Into<Arc<DType>>,
118 children: Vec<Scalar>,
119 nullability: Nullability,
120 ) -> Self {
121 Self::create_list(element_dtype, children, nullability, ListKind::Variable)
122 }
123
124 pub fn list_empty(element_dtype: Arc<DType>, nullability: Nullability) -> Self {
126 Self::create_list(element_dtype, vec![], nullability, ListKind::Variable)
127 }
128
129 pub fn fixed_size_list(
136 element_dtype: impl Into<Arc<DType>>,
137 children: Vec<Scalar>,
138 nullability: Nullability,
139 ) -> Self {
140 Self::create_list(element_dtype, children, nullability, ListKind::FixedSize)
141 }
142
143 pub fn map(dtype: DType, entries: impl IntoIterator<Item = (Scalar, Scalar)>) -> Self {
149 Self::try_map(dtype, entries).vortex_expect("unable to construct a map `Scalar`")
150 }
151
152 pub fn try_map(
159 dtype: DType,
160 entries: impl IntoIterator<Item = (Scalar, Scalar)>,
161 ) -> VortexResult<Self> {
162 let map = dtype
163 .as_map_opt()
164 .ok_or_else(|| vortex_error::vortex_err!("Expected map dtype, found {dtype}"))?;
165 let key_dtype = map.key_dtype();
166 let value_dtype = map.value_dtype();
167
168 let entries = entries
169 .into_iter()
170 .enumerate()
171 .map(|(index, (key, value))| {
172 if key.dtype() != &key_dtype {
173 vortex_bail!(
174 "map entry {index} expected key dtype {key_dtype}, got {}",
175 key.dtype()
176 );
177 }
178 if value.dtype() != &value_dtype {
179 vortex_bail!(
180 "map entry {index} expected value dtype {value_dtype}, got {}",
181 value.dtype()
182 );
183 }
184
185 Ok(Some(ScalarValue::Tuple(vec![
186 key.into_value(),
187 value.into_value(),
188 ])))
189 })
190 .collect::<VortexResult<Vec<_>>>()?;
191
192 Self::try_new(dtype, Some(ScalarValue::Tuple(entries)))
193 }
194
195 fn create_list(
197 element_dtype: impl Into<Arc<DType>>,
198 children: Vec<Scalar>,
199 nullability: Nullability,
200 list_kind: ListKind,
201 ) -> Self {
202 let element_dtype = element_dtype.into();
203
204 let children: Vec<Option<ScalarValue>> = children
205 .into_iter()
206 .map(|child| {
207 if child.dtype() != &*element_dtype {
208 vortex_panic!(
209 "tried to create list of {} with values of type {}",
210 element_dtype,
211 child.dtype()
212 );
213 }
214 child.into_value()
215 })
216 .collect();
217 let size: u32 = children
218 .len()
219 .try_into()
220 .vortex_expect("tried to create a list that was too large");
221
222 let dtype = match list_kind {
223 ListKind::Variable => DType::List(element_dtype, nullability),
224 ListKind::FixedSize => DType::FixedSizeList(element_dtype, size, nullability),
225 };
226
227 Self::try_new(dtype, Some(ScalarValue::Tuple(children)))
228 .vortex_expect("unable to construct a list `Scalar`")
229 }
230
231 pub fn extension<V: ExtVTable + Default>(options: V::Metadata, storage_scalar: Scalar) -> Self {
233 let ext_dtype = ExtDType::<V>::try_new(options, storage_scalar.dtype().clone())
234 .vortex_expect("Failed to create extension dtype");
235
236 Self::extension_ref(ext_dtype.erased(), storage_scalar)
237 }
238
239 pub fn extension_ref(ext_dtype: ExtDTypeRef, storage_scalar: Scalar) -> Self {
245 assert_eq!(ext_dtype.storage_dtype(), storage_scalar.dtype());
246
247 Self::try_new(DType::Extension(ext_dtype), storage_scalar.into_value())
248 .vortex_expect("unable to construct an extension `Scalar`")
249 }
250
251 pub fn union(
263 variants: UnionVariants,
264 type_id: u8,
265 child: Scalar,
266 nullability: Nullability,
267 ) -> VortexResult<Self> {
268 let child_index = variants.tag_to_child_index(type_id).ok_or_else(|| {
269 vortex_err!(
270 "union type ID {type_id} is not present in {:?}",
271 variants.type_ids()
272 )
273 })?;
274
275 let expected_dtype = variants
276 .variant_by_index(child_index)
277 .vortex_expect("type ID resolved to a valid child index");
278
279 vortex_ensure_eq!(
280 child.dtype(),
281 &expected_dtype,
282 "union type ID {type_id} selects child dtype {expected_dtype}, got {}",
283 child.dtype()
284 );
285
286 Self::try_new(
287 DType::Union(variants, nullability),
288 Some(ScalarValue::Union(UnionValue::new(
289 type_id,
290 child.into_value(),
291 ))),
292 )
293 }
294
295 pub fn variant(value: Scalar) -> Self {
301 Self::try_new(
302 DType::Variant(Nullability::NonNullable),
303 Some(ScalarValue::Variant(Box::new(value))),
304 )
305 .vortex_expect("unable to construct a variant `Scalar`")
306 }
307}
308
309enum ListKind {
311 Variable,
313 FixedSize,
315}