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#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Display, From)]
26pub enum Scalar {
27 Unit,
28 Bit(u8),
29 Bool(bool),
30 I64(i64),
32 F64(R64),
33 Decimal(Decimal),
34 #[display(fmt = "t'{}'", _0)]
36 Time(Time),
37 #[display(fmt = "d'{}'", _0)]
38 Date(Date),
39 #[display(fmt = "dt'{}'", _0)]
40 DateTime(DateTime),
41 #[display(fmt = "'{}'", _0)]
43 Char(char),
44 #[display(fmt = "'{}'", _0)]
45 UTF8(Rc<String>),
46 Sum(Box<SumVariant>),
48 Tuple(Rc<RelTuple>),
50 Vector(Rc<Vector>),
51 Tree(Rc<Tree>),
52 Map(Rc<Map>),
53 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
344pub 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}