1use ordered_float::OrderedFloat;
2use std::borrow::Cow;
3use std::fmt::{Debug, Display, Formatter};
4use std::hash::Hash;
5
6use rust_decimal::Decimal as RustDecimal;
7
8use crate::variant::Variant;
9use crate::{tuple, Bag, BindingIntoIter, BindingIter, DateTime, Graph, List, Tuple};
10use rust_decimal::prelude::FromPrimitive;
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14mod iter;
15mod logic;
16mod math;
17
18use crate::datum::{
19 Datum, DatumCategory, DatumCategoryOwned, DatumCategoryRef, DatumLower, DatumLowerResult,
20 DatumTupleOwned, DatumTupleRef, DatumValue,
21};
22pub use iter::*;
23pub use logic::*;
24pub use math::*;
25use partiql_common::pretty::ToPretty;
26use std::cmp::Ordering;
27
28#[derive(Hash, PartialEq, Eq, Clone, Default)]
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30pub enum Value {
31 Null,
32 #[default]
33 Missing,
34 Boolean(bool),
35 Integer(i64),
36 Real(OrderedFloat<f64>),
37 Decimal(Box<RustDecimal>),
38 String(Box<String>),
39 Blob(Box<Vec<u8>>),
40 DateTime(Box<DateTime>),
41 List(Box<List>),
42 Bag(Box<Bag>),
43 Tuple(Box<Tuple>),
44 Graph(Box<Graph>),
45 Variant(Box<Variant>),
46}
47
48impl Value {
49 #[inline]
50 #[must_use]
51 pub fn is_tuple(&self) -> bool {
52 matches!(self, Value::Tuple(_))
53 }
54
55 #[inline]
56 #[must_use]
57 pub fn is_list(&self) -> bool {
58 matches!(self, Value::List(_))
59 }
60
61 #[inline]
62 #[must_use]
63 pub fn is_bag(&self) -> bool {
64 matches!(self, Value::Bag(_))
65 }
66
67 #[inline]
68 #[must_use]
70 pub fn is_number(&self) -> bool {
71 matches!(self, Value::Integer(_) | Value::Real(_) | Value::Decimal(_))
72 }
73
74 #[inline]
75 #[must_use]
76 pub fn coerce_into_tuple(self) -> Tuple {
77 let coerce = |non_tuple: Value| {
78 non_tuple
79 .into_bindings()
80 .map(|(k, v)| (k.unwrap_or_else(|| "_1".to_string()), v))
81 .collect()
82 };
83
84 match self {
85 Value::Tuple(t) => *t,
86 Value::Variant(ref v) => match v.category() {
87 DatumCategoryRef::Tuple(_) => self
88 .into_lower()
89 .expect("variant lower")
90 .coerce_into_tuple(),
91 _ => coerce(self),
92 },
93 _ => coerce(self),
94 }
95 }
96
97 #[inline]
98 #[must_use]
99 pub fn coerce_to_tuple(&self) -> Tuple {
100 self.clone().coerce_into_tuple()
101 }
102
103 #[inline]
104 #[must_use]
105 pub fn as_datum_tuple_ref(&self) -> DatumTupleRef<'_> {
106 match self.category() {
107 DatumCategoryRef::Tuple(t) => t,
108 _ => DatumTupleRef::CoercedValue(1, self),
109 }
110 }
111
112 #[inline]
113 #[must_use]
114 pub fn as_tuple_ref(&self) -> Cow<'_, Tuple> {
115 match self.category() {
116 DatumCategoryRef::Tuple(t) => match t {
117 DatumTupleRef::Tuple(t) => Cow::Borrowed(t),
118 DatumTupleRef::Dynamic(_) => match self.lower().expect("variant lower") {
119 Cow::Borrowed(Value::Tuple(t)) => Cow::Borrowed(t.as_ref()),
120 Cow::Owned(Value::Tuple(t)) => Cow::Owned(*t),
121 _ => unreachable!(),
122 },
123 DatumTupleRef::Empty => Cow::Owned(tuple![]),
124 DatumTupleRef::CoercedValue(_, v) => Cow::Owned(tuple![("_1", v.clone())]),
125 DatumTupleRef::SingleKey(k, v) => Cow::Owned(tuple![(k.as_ref(), v.clone())]),
126 DatumTupleRef::Bindings(map) => Cow::Owned(Tuple::from_iter(
127 map.iter().map(|(k, &v)| (k.as_ref(), v.clone())),
128 )),
129 },
130 _ => Cow::Owned(self.coerce_to_tuple()),
131 }
132 }
133
134 #[inline]
135 #[must_use]
136 pub fn as_bindings(&self) -> BindingIter<'_> {
137 match self.category() {
138 DatumCategoryRef::Missing => BindingIter::Empty,
139 DatumCategoryRef::Tuple(t) => match t {
140 DatumTupleRef::Tuple(t) => BindingIter::Tuple(t.pairs()),
141 DatumTupleRef::Dynamic(_) => unreachable!(),
142 DatumTupleRef::Empty => BindingIter::Empty,
143 DatumTupleRef::CoercedValue(_, value) => {
144 BindingIter::Single(std::iter::once(value))
145 }
146 DatumTupleRef::SingleKey(_, value) => BindingIter::Single(std::iter::once(value)),
147 DatumTupleRef::Bindings(map) => {
148 let entries = map.iter().map(|(k, &v)| (Some(k.as_ref()), v));
149 BindingIter::Dynamic(Box::new(entries))
150 }
151 },
152 _ => BindingIter::Single(std::iter::once(self)),
153 }
154 }
155
156 #[inline]
157 #[must_use]
158 pub fn into_bindings(self) -> BindingIntoIter {
159 match self {
160 Value::Tuple(t) => BindingIntoIter::Tuple(t.into_pairs()),
161 Value::Missing => BindingIntoIter::Empty,
162 Value::Variant(v) => match v.category() {
163 DatumCategoryRef::Missing => BindingIntoIter::Empty,
164 DatumCategoryRef::Tuple(_) => match v.into_category() {
165 DatumCategoryOwned::Tuple(DatumTupleOwned::Tuple(t)) => {
166 BindingIntoIter::Tuple(t.into_pairs())
167 }
168 DatumCategoryOwned::Tuple(DatumTupleOwned::Dynamic(d)) => {
169 BindingIntoIter::DynTuple(d.into_iter_boxed())
170 }
171 _ => unreachable!(),
172 },
173 _ => BindingIntoIter::Single(std::iter::once(Value::Variant(v))),
174 },
175 _ => BindingIntoIter::Single(std::iter::once(self)),
176 }
177 }
178
179 #[inline]
180 #[must_use]
181 pub fn coerce_into_bag(self) -> Bag {
182 if let Value::Bag(b) = self {
183 *b
184 } else {
185 Bag::from(vec![self])
186 }
187 }
188
189 #[inline]
190 #[must_use]
191 pub fn as_bag_ref(&self) -> Cow<'_, Bag> {
192 if let Value::Bag(b) = self {
193 Cow::Borrowed(b)
194 } else {
195 Cow::Owned(self.clone().coerce_into_bag())
196 }
197 }
198
199 #[inline]
200 #[must_use]
201 pub fn coerce_into_list(self) -> List {
202 if let Value::List(b) = self {
203 *b
204 } else {
205 List::from(vec![self])
206 }
207 }
208
209 #[inline]
210 #[must_use]
211 pub fn as_list_ref(&self) -> Cow<'_, List> {
212 if let Value::List(l) = self {
213 Cow::Borrowed(l)
214 } else {
215 Cow::Owned(self.clone().coerce_into_list())
216 }
217 }
218
219 #[inline]
220 #[must_use]
221 pub fn iter(&self) -> ValueIter<'_> {
222 match self {
223 Value::Null | Value::Missing => ValueIter::Single(None),
224 Value::List(list) => ValueIter::List(list.iter()),
225 Value::Bag(bag) => ValueIter::Bag(bag.iter()),
226 other => ValueIter::Single(Some(other)),
227 }
228 }
229
230 #[inline]
231 #[must_use]
232 pub fn sequence_iter(&self) -> Option<ValueIter<'_>> {
233 if self.is_sequence() {
234 Some(self.iter())
235 } else {
236 None
237 }
238 }
239}
240
241impl DatumValue<Value> for Value {}
242
243impl DatumLower<Value> for Value {
244 fn into_lower(self) -> DatumLowerResult<Value> {
245 match self {
246 Value::Variant(variant) => variant.into_lower(),
247 _ => Ok(self),
248 }
249 }
250
251 fn into_lower_boxed(self: Box<Self>) -> DatumLowerResult<Value> {
252 self.into_lower()
253 }
254
255 fn lower(&self) -> DatumLowerResult<Cow<'_, Value>> {
256 match self {
257 Value::Variant(variant) => variant.lower(),
258 _ => Ok(Cow::Borrowed(self)),
259 }
260 }
261}
262
263impl Datum<Value> for Value {
264 #[inline]
265 fn is_null(&self) -> bool {
266 match self {
267 Value::Null => true,
268 Value::Variant(variant) => variant.is_null(),
269 _ => false,
270 }
271 }
272
273 #[inline]
274 fn is_missing(&self) -> bool {
275 match self {
276 Value::Missing => true,
277 Value::Variant(variant) => variant.is_missing(),
278 _ => false,
279 }
280 }
281
282 #[inline]
283 fn is_sequence(&self) -> bool {
284 match self {
285 Value::List(_) => true,
286 Value::Bag(_) => true,
287 Value::Variant(variant) => variant.is_sequence(),
288 _ => false,
289 }
290 }
291
292 #[inline]
293 fn is_ordered(&self) -> bool {
294 match self {
295 Value::List(_) => true,
296 Value::Variant(variant) => variant.is_ordered(),
297 _ => false,
298 }
299 }
300}
301
302impl Display for Value {
303 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
304 match self.to_pretty_string(f.width().unwrap_or(80)) {
305 Ok(pretty) => f.write_str(&pretty),
306 Err(_) => f.write_str("<internal value error occurred>"),
307 }
308 }
309}
310
311impl Debug for Value {
312 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
313 match self {
314 Value::Null => write!(f, "NULL"),
315 Value::Missing => write!(f, "MISSING"),
316 Value::Boolean(b) => write!(f, "{b}"),
317 Value::Integer(i) => write!(f, "{i}"),
318 Value::Real(r) => write!(f, "{}", r.0),
319 Value::Decimal(d) => write!(f, "{d}"),
320 Value::String(s) => write!(f, "'{s}'"),
321 Value::Blob(blob) => {
322 write!(f, "x'")?;
323 for byte in blob.as_ref() {
324 f.write_str(&format!("{byte:02x}"))?;
325 }
326 write!(f, "'")
327 }
328 Value::DateTime(t) => Debug::fmt(&t, f),
329 Value::List(l) => Debug::fmt(&l, f),
330 Value::Bag(b) => Debug::fmt(&b, f),
331 Value::Tuple(t) => Debug::fmt(&t, f),
332 Value::Graph(g) => Debug::fmt(&g, f),
333 Value::Variant(v) => Debug::fmt(&v, f),
334 }
335 }
336}
337
338impl PartialOrd for Value {
339 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
340 Some(self.cmp(other))
341 }
342}
343
344impl Ord for Value {
347 fn cmp(&self, other: &Self) -> Ordering {
348 match (self, other) {
350 (Value::Null, Value::Null) => Ordering::Equal,
351 (Value::Missing, Value::Null) => Ordering::Equal,
352
353 (Value::Null, Value::Missing) => Ordering::Equal,
354 (Value::Null, _) => Ordering::Less,
355 (_, Value::Null) => Ordering::Greater,
356
357 (Value::Missing, Value::Missing) => Ordering::Equal,
358 (Value::Missing, _) => Ordering::Less,
359 (_, Value::Missing) => Ordering::Greater,
360
361 (Value::Boolean(l), Value::Boolean(r)) => match (l, r) {
362 (false, true) => Ordering::Less,
363 (true, false) => Ordering::Greater,
364 (_, _) => Ordering::Equal,
365 },
366 (Value::Boolean(_), _) => Ordering::Less,
367 (_, Value::Boolean(_)) => Ordering::Greater,
368
369 (Value::Real(l), Value::Real(r)) => {
376 if l.is_nan() {
377 if r.is_nan() {
378 Ordering::Equal
379 } else {
380 Ordering::Less
381 }
382 } else if r.is_nan() {
383 Ordering::Greater
384 } else {
385 l.cmp(r)
386 }
387 }
388 (Value::Integer(l), Value::Integer(r)) => l.cmp(r),
389 (Value::Decimal(l), Value::Decimal(r)) => l.cmp(r),
390 (Value::Integer(l), Value::Real(_)) => {
391 Value::Real(ordered_float::OrderedFloat(*l as f64)).cmp(other)
392 }
393 (Value::Real(_), Value::Integer(r)) => {
394 self.cmp(&Value::Real(ordered_float::OrderedFloat(*r as f64)))
395 }
396 (Value::Integer(l), Value::Decimal(r)) => RustDecimal::from(*l).cmp(r),
397 (Value::Decimal(l), Value::Integer(r)) => l.as_ref().cmp(&RustDecimal::from(*r)),
398 (Value::Real(l), Value::Decimal(r)) => {
399 if l.is_nan() || l.0 == f64::NEG_INFINITY {
400 Ordering::Less
401 } else if l.0 == f64::INFINITY {
402 Ordering::Greater
403 } else {
404 match RustDecimal::from_f64(l.0) {
405 Some(l_d) => l_d.cmp(r),
406 None => todo!(
407 "Decide default behavior when f64 can't be converted to RustDecimal"
408 ),
409 }
410 }
411 }
412 (Value::Decimal(l), Value::Real(r)) => {
413 if r.is_nan() || r.0 == f64::NEG_INFINITY {
414 Ordering::Greater
415 } else if r.0 == f64::INFINITY {
416 Ordering::Less
417 } else {
418 match RustDecimal::from_f64(r.0) {
419 Some(r_d) => l.as_ref().cmp(&r_d),
420 None => todo!(
421 "Decide default behavior when f64 can't be converted to RustDecimal"
422 ),
423 }
424 }
425 }
426 (Value::Integer(_), _) => Ordering::Less,
427 (Value::Real(_), _) => Ordering::Less,
428 (Value::Decimal(_), _) => Ordering::Less,
429 (_, Value::Integer(_)) => Ordering::Greater,
430 (_, Value::Real(_)) => Ordering::Greater,
431 (_, Value::Decimal(_)) => Ordering::Greater,
432
433 (Value::DateTime(l), Value::DateTime(r)) => l.cmp(r),
434 (Value::DateTime(_), _) => Ordering::Less,
435 (_, Value::DateTime(_)) => Ordering::Greater,
436
437 (Value::String(l), Value::String(r)) => l.cmp(r),
438 (Value::String(_), _) => Ordering::Less,
439 (_, Value::String(_)) => Ordering::Greater,
440
441 (Value::Blob(l), Value::Blob(r)) => l.cmp(r),
442 (Value::Blob(_), _) => Ordering::Less,
443 (_, Value::Blob(_)) => Ordering::Greater,
444
445 (Value::List(l), Value::List(r)) => l.cmp(r),
446 (Value::List(_), _) => Ordering::Less,
447 (_, Value::List(_)) => Ordering::Greater,
448
449 (Value::Tuple(l), Value::Tuple(r)) => l.cmp(r),
450 (Value::Tuple(_), _) => Ordering::Less,
451 (_, Value::Tuple(_)) => Ordering::Greater,
452
453 (Value::Bag(l), Value::Bag(r)) => l.cmp(r),
454 (Value::Bag(_), _) => Ordering::Less,
455 (_, Value::Bag(_)) => Ordering::Greater,
456
457 (Value::Graph(l), Value::Graph(r)) => l.cmp(r),
459 (Value::Graph(_), _) => Ordering::Less,
460 (_, Value::Graph(_)) => Ordering::Greater,
461
462 (Value::Variant(l), Value::Variant(r)) => l.cmp(r),
463 }
464 }
465}
466
467impl From<bool> for Value {
468 #[inline]
469 fn from(b: bool) -> Self {
470 Value::Boolean(b)
471 }
472}
473
474impl From<String> for Value {
475 #[inline]
476 fn from(s: String) -> Self {
477 Value::String(Box::new(s))
478 }
479}
480
481impl From<&str> for Value {
482 #[inline]
483 fn from(s: &str) -> Self {
484 Value::String(Box::new(s.to_string()))
485 }
486}
487
488impl From<i128> for Value {
489 #[inline]
490 fn from(n: i128) -> Self {
491 Value::from(RustDecimal::from(n))
492 }
493}
494
495impl From<i64> for Value {
496 #[inline]
497 fn from(n: i64) -> Self {
498 Value::Integer(n)
499 }
500}
501
502impl From<i32> for Value {
503 #[inline]
504 fn from(n: i32) -> Self {
505 i64::from(n).into()
506 }
507}
508
509impl From<i16> for Value {
510 #[inline]
511 fn from(n: i16) -> Self {
512 i64::from(n).into()
513 }
514}
515
516impl From<i8> for Value {
517 #[inline]
518 fn from(n: i8) -> Self {
519 i64::from(n).into()
520 }
521}
522
523impl From<usize> for Value {
524 #[inline]
525 fn from(n: usize) -> Self {
526 if n > i64::MAX as usize {
527 Value::from(RustDecimal::from(n))
528 } else {
529 Value::Integer(n as i64)
530 }
531 }
532}
533
534impl From<u8> for Value {
535 #[inline]
536 fn from(n: u8) -> Self {
537 (n as usize).into()
538 }
539}
540
541impl From<u16> for Value {
542 #[inline]
543 fn from(n: u16) -> Self {
544 (n as usize).into()
545 }
546}
547
548impl From<u32> for Value {
549 #[inline]
550 fn from(n: u32) -> Self {
551 (n as usize).into()
552 }
553}
554
555impl From<u64> for Value {
556 #[inline]
557 fn from(n: u64) -> Self {
558 (n as usize).into()
559 }
560}
561
562impl From<u128> for Value {
563 #[inline]
564 fn from(n: u128) -> Self {
565 Value::from(RustDecimal::from(n))
566 }
567}
568
569impl From<f64> for Value {
570 #[inline]
571 fn from(f: f64) -> Self {
572 Value::from(OrderedFloat(f))
573 }
574}
575
576impl From<OrderedFloat<f64>> for Value {
577 #[inline]
578 fn from(f: OrderedFloat<f64>) -> Self {
579 Value::Real(f)
580 }
581}
582
583impl From<RustDecimal> for Value {
584 #[inline]
585 fn from(d: RustDecimal) -> Self {
586 Value::Decimal(Box::new(d))
587 }
588}
589
590impl From<DateTime> for Value {
591 #[inline]
592 fn from(t: DateTime) -> Self {
593 Value::DateTime(Box::new(t))
594 }
595}
596
597impl From<List> for Value {
598 #[inline]
599 fn from(v: List) -> Self {
600 Value::List(Box::new(v))
601 }
602}
603
604impl From<Tuple> for Value {
605 #[inline]
606 fn from(v: Tuple) -> Self {
607 Value::Tuple(Box::new(v))
608 }
609}
610
611impl From<Bag> for Value {
612 #[inline]
613 fn from(v: Bag) -> Self {
614 Value::Bag(Box::new(v))
615 }
616}
617
618impl From<Graph> for Value {
619 #[inline]
620 fn from(g: Graph) -> Self {
621 Value::Graph(Box::new(g))
622 }
623}
624
625impl From<Variant> for Value {
626 #[inline]
627 fn from(v: Variant) -> Self {
628 Value::Variant(Box::new(v))
629 }
630}