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