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