tablam/
scalar.rs

1use std::hash::Hash;
2use std::rc::Rc;
3
4use decorum::R64;
5use derive_more::{Display, From};
6use rust_decimal::Decimal;
7
8use crate::dsl::schema_it;
9use crate::errors;
10use crate::for_impl::*;
11use crate::map::Map;
12use crate::schema::Schema;
13use crate::stdlib::io::File;
14use crate::sum_type::SumVariant;
15use crate::tree::Tree;
16use crate::tuple::RelTuple;
17use crate::types::{DataType, NativeKind, Rel, RelShape, Relation, Tuple};
18use crate::vector::Vector;
19
20pub type DateTime = chrono::DateTime<chrono::FixedOffset>;
21pub type Date = chrono::Date<chrono::FixedOffset>;
22pub type Time = chrono::NaiveTime;
23
24//NOTE: The order of this enum must match DataType
25#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Display, From)]
26pub enum Scalar {
27    Unit,
28    Bit(u8),
29    Bool(bool),
30    //Numeric
31    I64(i64),
32    F64(R64),
33    Decimal(Decimal),
34    //Date
35    #[display(fmt = "t'{}'", _0)]
36    Time(Time),
37    #[display(fmt = "d'{}'", _0)]
38    Date(Date),
39    #[display(fmt = "dt'{}'", _0)]
40    DateTime(DateTime),
41    //Strings
42    #[display(fmt = "'{}'", _0)]
43    Char(char),
44    #[display(fmt = "'{}'", _0)]
45    UTF8(Rc<String>),
46    //Sum types
47    Sum(Box<SumVariant>),
48    //Collections
49    Tuple(Rc<RelTuple>),
50    Vector(Rc<Vector>),
51    Tree(Rc<Tree>),
52    Map(Rc<Map>),
53    //Lazy computation
54    //Seq(Seq<'static>),
55    //Objects
56    File(Box<File>),
57    Rel(Relation),
58    Top,
59}
60
61impl Scalar {
62    pub fn repeat(&self, times: usize) -> Tuple {
63        (0..times).map(|_| self.clone()).collect()
64    }
65
66    pub fn rows_iter(&self) -> Box<dyn Iterator<Item = Tuple> + '_> {
67        match self {
68            Scalar::Vector(x) => Box::new(x.rows_iter()),
69            Scalar::File(x) => Box::new(x.rows_iter()),
70            x => Box::new(std::iter::once(x.clone()).map(|x| vec![x])),
71        }
72    }
73
74    pub fn to_scalar(&self) -> Option<Scalar> {
75        if !self.is_scalar() {
76            return None;
77        }
78
79        match self {
80            Scalar::Vector(x) => Some(x.data[0].clone()),
81            Scalar::File(_) => None,
82            x => Some(x.clone()),
83        }
84    }
85}
86
87impl Rel for Scalar {
88    fn type_name(&self) -> &str {
89        match self {
90            Scalar::Unit => "None",
91            Scalar::Bit(_) => "Bit",
92            Scalar::Bool(_) => "Bool",
93            Scalar::Char(_) => "Char",
94            Scalar::Date(_) => "Date",
95            Scalar::DateTime(_) => "DateTime",
96            Scalar::Decimal(_) => "Decimal",
97            Scalar::F64(_) => "F64",
98            Scalar::I64(_) => "I64",
99            Scalar::Time(_) => "Time",
100            Scalar::UTF8(_) => "UTF8",
101            Scalar::Sum(_) => "Sum",
102            Scalar::Vector(x) => x.type_name(),
103            Scalar::Tuple(x) => x.type_name(),
104            Scalar::Tree(x) => x.type_name(),
105            Scalar::Map(x) => x.type_name(),
106            Scalar::File(x) => x.type_name(),
107            Scalar::Rel(_) => "Rel",
108            Scalar::Top => "Top",
109        }
110    }
111
112    fn kind(&self) -> DataType {
113        match self {
114            Scalar::Unit => DataType::Unit,
115            Scalar::Bit(_) => DataType::Bit,
116            Scalar::Bool(_) => DataType::Bool,
117            Scalar::Char(_) => DataType::Char,
118            Scalar::Date(_) => DataType::Date,
119            Scalar::DateTime(_) => DataType::DateTime,
120            Scalar::Decimal(_) => DataType::Decimal,
121            Scalar::F64(_) => DataType::F64,
122            Scalar::I64(_) => DataType::I64,
123            Scalar::Time(_) => DataType::Time,
124            Scalar::UTF8(_) => DataType::UTF8,
125            Scalar::Sum(x) => x.kind(),
126            Scalar::Tuple(x) => x.kind(),
127            Scalar::Vector(x) => x.kind(),
128            Scalar::Tree(x) => x.kind(),
129            Scalar::Map(x) => x.kind(),
130            Scalar::Rel(x) => x.rel.kind(),
131            Scalar::File(x) => x.kind(),
132            Scalar::Top => DataType::ANY,
133        }
134    }
135
136    fn schema(&self) -> Schema {
137        match self {
138            Scalar::Vector(x) => x.schema(),
139            Scalar::Tuple(x) => x.schema(),
140            Scalar::Tree(x) => x.schema(),
141            Scalar::Map(x) => x.schema(),
142            Scalar::Rel(x) => x.rel.schema(),
143            Scalar::File(x) => x.schema(),
144            x => schema_it(x.kind()),
145        }
146    }
147
148    fn len(&self) -> usize {
149        match self {
150            Scalar::Vector(x) => x.len(),
151            Scalar::Tuple(x) => x.len(),
152            Scalar::Tree(x) => x.len(),
153            Scalar::Map(x) => x.len(),
154            Scalar::Rel(x) => x.rel.len(),
155            Scalar::File(x) => x.len(),
156            _ => 1,
157        }
158    }
159
160    fn cols(&self) -> usize {
161        match self {
162            Scalar::Vector(x) => x.cols(),
163            Scalar::Tuple(x) => x.cols(),
164            Scalar::Tree(x) => x.cols(),
165            Scalar::Map(x) => x.cols(),
166            Scalar::Rel(x) => x.rel.cols(),
167            Scalar::File(x) => x.cols(),
168            _ => 1,
169        }
170    }
171
172    fn rows(&self) -> Option<usize> {
173        match self {
174            Scalar::Vector(x) => x.rows(),
175            Scalar::Tuple(x) => x.rows(),
176            Scalar::Tree(x) => x.rows(),
177            Scalar::Map(x) => x.rows(),
178            Scalar::Rel(x) => x.rel.rows(),
179            Scalar::File(x) => x.rows(),
180            _ => Some(1),
181        }
182    }
183
184    fn as_any(&self) -> &dyn Any {
185        self
186    }
187
188    fn rel_shape(&self) -> RelShape {
189        match self {
190            Scalar::Vector(x) => x.rel_shape(),
191            Scalar::Tuple(x) => x.rel_shape(),
192            Scalar::Tree(x) => x.rel_shape(),
193            Scalar::Map(x) => x.rel_shape(),
194            Scalar::Rel(x) => x.rel.rel_shape(),
195            Scalar::File(x) => x.rel_shape(),
196            _ => RelShape::Scalar,
197        }
198    }
199
200    fn rel_hash(&self, mut hasher: &mut dyn Hasher) {
201        match self {
202            Scalar::Vector(x) => x.rel_hash(&mut hasher),
203            Scalar::Tuple(x) => x.rel_hash(&mut hasher),
204            Scalar::Tree(x) => x.rel_hash(&mut hasher),
205            Scalar::Map(x) => x.rel_hash(&mut hasher),
206            Scalar::Rel(x) => x.rel.rel_hash(&mut hasher),
207            Scalar::File(x) => x.rel_hash(&mut hasher),
208            x => x.hash(&mut hasher),
209        }
210    }
211
212    fn rel_eq(&self, other: &dyn Rel) -> bool {
213        cmp_eq(self, other)
214    }
215
216    fn rel_cmp(&self, other: &dyn Rel) -> Ordering {
217        cmp(self, other)
218    }
219}
220
221pub fn select(of: &[Scalar], cols: &[usize]) -> Tuple {
222    if cols.is_empty() {
223        vec![]
224    } else {
225        let mut cells = Vec::with_capacity(cols.len());
226        for p in cols {
227            cells.push(of[*p].clone());
228        }
229        cells
230    }
231}
232
233pub(crate) fn combine(lhs: &[Scalar], rhs: &[Scalar]) -> Tuple {
234    lhs.iter().chain(rhs.iter()).cloned().collect()
235}
236
237macro_rules! kind_native {
238    ($native:ident, $kind:ident) => {
239        impl NativeKind for $native {
240            fn kind() -> DataType {
241                DataType::$kind
242            }
243        }
244    };
245}
246
247impl NativeKind for &str {
248    fn kind() -> DataType {
249        DataType::UTF8
250    }
251}
252
253kind_native!(i64, I64);
254kind_native!(bool, Bool);
255kind_native!(Decimal, Decimal);
256kind_native!(R64, F64);
257kind_native!(f64, F64);
258kind_native!(String, UTF8);
259
260impl From<i32> for Scalar {
261    fn from(x: i32) -> Self {
262        Scalar::I64(x as i64)
263    }
264}
265
266impl From<f64> for Scalar {
267    fn from(x: f64) -> Self {
268        Scalar::F64(x.into())
269    }
270}
271
272impl From<&str> for Scalar {
273    fn from(x: &str) -> Self {
274        Scalar::UTF8(Rc::new(x.into()))
275    }
276}
277
278impl From<&char> for Scalar {
279    fn from(x: &char) -> Self {
280        Scalar::Char(*x)
281    }
282}
283
284impl From<String> for Scalar {
285    fn from(x: String) -> Self {
286        Scalar::UTF8(Rc::new(x))
287    }
288}
289
290impl From<Box<Scalar>> for Scalar {
291    fn from(x: Box<Scalar>) -> Self {
292        *x
293    }
294}
295
296impl From<SumVariant> for Scalar {
297    fn from(x: SumVariant) -> Self {
298        Scalar::Sum(Box::new(x))
299    }
300}
301
302impl From<Vector> for Scalar {
303    fn from(x: Vector) -> Self {
304        Scalar::Vector(Rc::new(x))
305    }
306}
307
308macro_rules! convert {
309    ($kind:ident, $bound:path) => {
310        impl From<Scalar> for $kind {
311            fn from(i: Scalar) -> Self {
312                match i {
313                    $bound(x) => x,
314                    _ => unreachable!("{:?}", i),
315                }
316            }
317        }
318
319        impl<'a> From<&'a Scalar> for $kind {
320            fn from(i: &'a Scalar) -> Self {
321                match i {
322                    $bound(x) => x.clone(),
323                    _ => unreachable!("{:?}", i),
324                }
325            }
326        }
327    };
328}
329
330convert!(bool, Scalar::Bool);
331convert!(i64, Scalar::I64);
332convert!(R64, Scalar::F64);
333convert!(Decimal, Scalar::Decimal);
334
335impl From<Scalar> for String {
336    fn from(i: Scalar) -> Self {
337        match i {
338            Scalar::UTF8(x) => x.to_string(),
339            _ => unreachable!("{:?}", i),
340        }
341    }
342}
343
344/// Provide support for broadcast a function over scalars and vectors
345pub fn fold_fn2<F>(x: &Scalar, y: &Scalar, apply: F) -> errors::Result<Scalar>
346where
347    F: Fn(&[Scalar]) -> errors::Result<Scalar>,
348{
349    let data = match (x, y) {
350        (Scalar::Vector(a), Scalar::Vector(b)) => {
351            if a.shape != b.shape {
352                return Err(errors::Error::RankNotMatch);
353            }
354            let mut data = Vec::with_capacity(a.data.len());
355
356            for (lhs, rhs) in a.data.iter().zip(b.data.iter()) {
357                data.push(apply(&[lhs.clone(), rhs.clone()])?);
358            }
359
360            Ok(Vector::new_vector(data, a.kind()))
361        }
362        (_, Scalar::Vector(data)) => data.fold_fn(x, apply),
363        (Scalar::Vector(data), _) => data.fold_fn(y, apply),
364        _ => return Err(errors::Error::TypeMismatchBinOp(x.kind(), y.kind())),
365    }?;
366    Ok(data.into())
367}