1use std::cmp::Ordering;
21use std::fmt::{Display, Formatter, LowerExp};
22use std::str::FromStr;
23
24use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
25use ordered_float::{Float, OrderedFloat};
26use serde::de::{self, MapAccess};
27use serde::ser::SerializeStruct;
28use serde::{Deserialize, Serialize};
29use serde_bytes::ByteBuf;
30
31use super::decimal_utils::{
32 Decimal, decimal_from_i128_with_scale, decimal_from_str_exact, decimal_mantissa,
33 decimal_precision, decimal_scale, i128_from_be_bytes, i128_to_be_bytes_min,
34};
35use super::literal::Literal;
36use super::primitive::PrimitiveLiteral;
37use super::serde::_serde::RawLiteral;
38use super::temporal::{date, time, timestamp, timestamptz};
39use crate::ensure_data_valid;
40use crate::error::{Error, ErrorKind, Result, invalid_data};
41use crate::spec::MAX_DECIMAL_PRECISION;
42use crate::spec::datatypes::{PrimitiveType, Type};
43
44pub(crate) const MAX_TIME_VALUE: i64 = 24 * 60 * 60 * 1_000_000i64 - 1;
46
47pub(crate) const INT_MAX: i32 = 2147483647;
48pub(crate) const INT_MIN: i32 = -2147483648;
49pub(crate) const LONG_MAX: i64 = 9223372036854775807;
50pub(crate) const LONG_MIN: i64 = -9223372036854775808;
51
52#[derive(Clone, Debug, PartialEq, Hash, Eq)]
58pub struct Datum {
59 r#type: PrimitiveType,
60 literal: PrimitiveLiteral,
61}
62
63impl Serialize for Datum {
64 fn serialize<S: serde::Serializer>(
65 &self,
66 serializer: S,
67 ) -> std::result::Result<S::Ok, S::Error> {
68 let mut struct_ser = serializer
69 .serialize_struct("Datum", 2)
70 .map_err(serde::ser::Error::custom)?;
71 struct_ser
72 .serialize_field("type", &self.r#type)
73 .map_err(serde::ser::Error::custom)?;
74 struct_ser
75 .serialize_field(
76 "literal",
77 &RawLiteral::try_from(
78 Literal::Primitive(self.literal.clone()),
79 &Type::Primitive(self.r#type.clone()),
80 )
81 .map_err(serde::ser::Error::custom)?,
82 )
83 .map_err(serde::ser::Error::custom)?;
84 struct_ser.end()
85 }
86}
87
88impl<'de> Deserialize<'de> for Datum {
89 fn deserialize<D: serde::Deserializer<'de>>(
90 deserializer: D,
91 ) -> std::result::Result<Self, D::Error> {
92 #[derive(Deserialize)]
93 #[serde(field_identifier, rename_all = "lowercase")]
94 enum Field {
95 Type,
96 Literal,
97 }
98
99 struct DatumVisitor;
100
101 impl<'de> de::Visitor<'de> for DatumVisitor {
102 type Value = Datum;
103
104 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
105 formatter.write_str("struct Datum")
106 }
107
108 fn visit_seq<A>(self, mut seq: A) -> std::result::Result<Self::Value, A::Error>
109 where A: de::SeqAccess<'de> {
110 let r#type = seq
111 .next_element::<PrimitiveType>()?
112 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
113 let value = seq
114 .next_element::<RawLiteral>()?
115 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
116 let Literal::Primitive(primitive) = value
117 .try_into(&Type::Primitive(r#type.clone()))
118 .map_err(de::Error::custom)?
119 .ok_or_else(|| de::Error::custom("None value"))?
120 else {
121 return Err(de::Error::custom("Invalid value"));
122 };
123
124 Ok(Datum::new(r#type, primitive))
125 }
126
127 fn visit_map<V>(self, mut map: V) -> std::result::Result<Datum, V::Error>
128 where V: MapAccess<'de> {
129 let mut raw_primitive: Option<RawLiteral> = None;
130 let mut r#type: Option<PrimitiveType> = None;
131 while let Some(key) = map.next_key()? {
132 match key {
133 Field::Type => {
134 if r#type.is_some() {
135 return Err(de::Error::duplicate_field("type"));
136 }
137 r#type = Some(map.next_value()?);
138 }
139 Field::Literal => {
140 if raw_primitive.is_some() {
141 return Err(de::Error::duplicate_field("literal"));
142 }
143 raw_primitive = Some(map.next_value()?);
144 }
145 }
146 }
147 let Some(r#type) = r#type else {
148 return Err(de::Error::missing_field("type"));
149 };
150 let Some(raw_primitive) = raw_primitive else {
151 return Err(de::Error::missing_field("literal"));
152 };
153 let Literal::Primitive(primitive) = raw_primitive
154 .try_into(&Type::Primitive(r#type.clone()))
155 .map_err(de::Error::custom)?
156 .ok_or_else(|| de::Error::custom("None value"))?
157 else {
158 return Err(de::Error::custom("Invalid value"));
159 };
160 Ok(Datum::new(r#type, primitive))
161 }
162 }
163 const FIELDS: &[&str] = &["type", "literal"];
164 deserializer.deserialize_struct("Datum", FIELDS, DatumVisitor)
165 }
166}
167
168fn iceberg_float_cmp_f32(a: OrderedFloat<f32>, b: OrderedFloat<f32>) -> Option<Ordering> {
171 Some(a.total_cmp(&b))
172}
173
174fn iceberg_float_cmp_f64(a: OrderedFloat<f64>, b: OrderedFloat<f64>) -> Option<Ordering> {
175 Some(a.total_cmp(&b))
176}
177
178impl PartialOrd for Datum {
179 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
180 match (&self.literal, &other.literal, &self.r#type, &other.r#type) {
181 (
183 PrimitiveLiteral::Boolean(val),
184 PrimitiveLiteral::Boolean(other_val),
185 PrimitiveType::Boolean,
186 PrimitiveType::Boolean,
187 ) => val.partial_cmp(other_val),
188 (
189 PrimitiveLiteral::Int(val),
190 PrimitiveLiteral::Int(other_val),
191 PrimitiveType::Int,
192 PrimitiveType::Int,
193 ) => val.partial_cmp(other_val),
194 (
195 PrimitiveLiteral::Long(val),
196 PrimitiveLiteral::Long(other_val),
197 PrimitiveType::Long,
198 PrimitiveType::Long,
199 ) => val.partial_cmp(other_val),
200 (
201 PrimitiveLiteral::Float(val),
202 PrimitiveLiteral::Float(other_val),
203 PrimitiveType::Float,
204 PrimitiveType::Float,
205 ) => iceberg_float_cmp_f32(*val, *other_val),
206 (
207 PrimitiveLiteral::Double(val),
208 PrimitiveLiteral::Double(other_val),
209 PrimitiveType::Double,
210 PrimitiveType::Double,
211 ) => iceberg_float_cmp_f64(*val, *other_val),
212 (
213 PrimitiveLiteral::Int(val),
214 PrimitiveLiteral::Int(other_val),
215 PrimitiveType::Date,
216 PrimitiveType::Date,
217 ) => val.partial_cmp(other_val),
218 (
219 PrimitiveLiteral::Long(val),
220 PrimitiveLiteral::Long(other_val),
221 PrimitiveType::Time,
222 PrimitiveType::Time,
223 ) => val.partial_cmp(other_val),
224 (
225 PrimitiveLiteral::Long(val),
226 PrimitiveLiteral::Long(other_val),
227 PrimitiveType::Timestamp,
228 PrimitiveType::Timestamp,
229 ) => val.partial_cmp(other_val),
230 (
231 PrimitiveLiteral::Long(val),
232 PrimitiveLiteral::Long(other_val),
233 PrimitiveType::Timestamptz,
234 PrimitiveType::Timestamptz,
235 ) => val.partial_cmp(other_val),
236 (
237 PrimitiveLiteral::Long(val),
238 PrimitiveLiteral::Long(other_val),
239 PrimitiveType::TimestampNs,
240 PrimitiveType::TimestampNs,
241 ) => val.partial_cmp(other_val),
242 (
243 PrimitiveLiteral::Long(val),
244 PrimitiveLiteral::Long(other_val),
245 PrimitiveType::TimestamptzNs,
246 PrimitiveType::TimestamptzNs,
247 ) => val.partial_cmp(other_val),
248 (
249 PrimitiveLiteral::String(val),
250 PrimitiveLiteral::String(other_val),
251 PrimitiveType::String,
252 PrimitiveType::String,
253 ) => val.partial_cmp(other_val),
254 (
255 PrimitiveLiteral::UInt128(val),
256 PrimitiveLiteral::UInt128(other_val),
257 PrimitiveType::Uuid,
258 PrimitiveType::Uuid,
259 ) => uuid::Uuid::from_u128(*val).partial_cmp(&uuid::Uuid::from_u128(*other_val)),
260 (
261 PrimitiveLiteral::Binary(val),
262 PrimitiveLiteral::Binary(other_val),
263 PrimitiveType::Fixed(_),
264 PrimitiveType::Fixed(_),
265 ) => val.partial_cmp(other_val),
266 (
267 PrimitiveLiteral::Binary(val),
268 PrimitiveLiteral::Binary(other_val),
269 PrimitiveType::Binary,
270 PrimitiveType::Binary,
271 ) => val.partial_cmp(other_val),
272 (
273 PrimitiveLiteral::Binary(_),
274 PrimitiveLiteral::Binary(_),
275 PrimitiveType::Geometry(_) | PrimitiveType::Geography(_),
276 PrimitiveType::Geometry(_) | PrimitiveType::Geography(_),
277 ) => None,
278 (
279 PrimitiveLiteral::Int128(val),
280 PrimitiveLiteral::Int128(other_val),
281 PrimitiveType::Decimal {
282 precision: _,
283 scale,
284 },
285 PrimitiveType::Decimal {
286 precision: _,
287 scale: other_scale,
288 },
289 ) => {
290 let val = decimal_from_i128_with_scale(*val, *scale);
291 let other_val = decimal_from_i128_with_scale(*other_val, *other_scale);
292 val.partial_cmp(&other_val)
293 }
294 _ => None,
295 }
296 }
297}
298
299impl Display for Datum {
300 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
301 match (&self.r#type, &self.literal) {
302 (_, PrimitiveLiteral::Boolean(val)) => write!(f, "{val}"),
303 (
304 PrimitiveType::Int | PrimitiveType::Long | PrimitiveType::Unknown,
305 PrimitiveLiteral::Int(val),
306 ) => {
307 write!(f, "{val}")
308 }
309 (
310 PrimitiveType::Int | PrimitiveType::Long | PrimitiveType::Unknown,
311 PrimitiveLiteral::Long(val),
312 ) => {
313 write!(f, "{val}")
314 }
315 (_, PrimitiveLiteral::Float(val)) => write!(f, "{val}"),
316 (_, PrimitiveLiteral::Double(val)) => write!(f, "{val}"),
317 (PrimitiveType::Date, PrimitiveLiteral::Int(val)) => {
318 write!(f, "{}", date::days_to_date(*val))
319 }
320 (PrimitiveType::Time, PrimitiveLiteral::Long(val)) => {
321 write!(f, "{}", time::microseconds_to_time(*val))
322 }
323 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(val)) => {
324 write!(f, "{}", timestamp::microseconds_to_datetime(*val))
325 }
326 (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(val)) => {
327 write!(f, "{}", timestamptz::microseconds_to_datetimetz(*val))
328 }
329 (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(val)) => {
330 write!(f, "{}", timestamp::nanoseconds_to_datetime(*val))
331 }
332 (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(val)) => {
333 write!(f, "{}", timestamptz::nanoseconds_to_datetimetz(*val))
334 }
335 (_, PrimitiveLiteral::String(val)) => write!(f, r#""{val}""#),
336 (PrimitiveType::Uuid | PrimitiveType::Unknown, PrimitiveLiteral::UInt128(val)) => {
337 write!(f, "{}", uuid::Uuid::from_u128(*val))
338 }
339 (_, PrimitiveLiteral::Binary(val)) => display_bytes(val, f),
340 (
341 PrimitiveType::Decimal {
342 precision: _,
343 scale,
344 },
345 PrimitiveLiteral::Int128(val),
346 ) => {
347 write!(f, "{}", decimal_from_i128_with_scale(*val, *scale))
348 }
349 (PrimitiveType::Unknown, PrimitiveLiteral::Int128(val)) => write!(f, "{val}"),
351 (_, _) => {
352 unreachable!()
353 }
354 }
355 }
356}
357
358fn display_bytes(bytes: &[u8], f: &mut Formatter<'_>) -> std::fmt::Result {
359 let mut s = String::with_capacity(bytes.len() * 2);
360 for b in bytes {
361 s.push_str(&format!("{b:02X}"));
362 }
363 f.write_str(&s)
364}
365
366impl From<Datum> for Literal {
367 fn from(value: Datum) -> Self {
368 Literal::Primitive(value.literal)
369 }
370}
371
372impl From<Datum> for PrimitiveLiteral {
373 fn from(value: Datum) -> Self {
374 value.literal
375 }
376}
377
378impl Datum {
379 pub(crate) fn new(r#type: PrimitiveType, literal: PrimitiveLiteral) -> Self {
381 Datum { r#type, literal }
382 }
383
384 pub fn try_from_bytes(bytes: &[u8], data_type: PrimitiveType) -> Result<Self> {
388 let literal = match data_type {
389 PrimitiveType::Unknown => {
390 return Err(Error::new(
391 ErrorKind::FeatureUnsupported,
392 "Cannot create datum for unknown type from bytes",
393 ));
394 }
395 PrimitiveType::Boolean => {
396 if bytes.len() == 1 && bytes[0] == 0u8 {
397 PrimitiveLiteral::Boolean(false)
398 } else {
399 PrimitiveLiteral::Boolean(true)
400 }
401 }
402 PrimitiveType::Int => PrimitiveLiteral::Int(i32::from_le_bytes(bytes.try_into()?)),
403 PrimitiveType::Long => {
404 if bytes.len() == 4 {
405 PrimitiveLiteral::Long(i32::from_le_bytes(bytes.try_into()?) as i64)
407 } else {
408 PrimitiveLiteral::Long(i64::from_le_bytes(bytes.try_into()?))
409 }
410 }
411 PrimitiveType::Float => {
412 PrimitiveLiteral::Float(OrderedFloat(f32::from_le_bytes(bytes.try_into()?)))
413 }
414 PrimitiveType::Double => {
415 if bytes.len() == 4 {
416 PrimitiveLiteral::Double(OrderedFloat(
418 f32::from_le_bytes(bytes.try_into()?) as f64
419 ))
420 } else {
421 PrimitiveLiteral::Double(OrderedFloat(f64::from_le_bytes(bytes.try_into()?)))
422 }
423 }
424 PrimitiveType::Date => PrimitiveLiteral::Int(i32::from_le_bytes(bytes.try_into()?)),
425 PrimitiveType::Time => PrimitiveLiteral::Long(i64::from_le_bytes(bytes.try_into()?)),
426 PrimitiveType::Timestamp => {
427 PrimitiveLiteral::Long(i64::from_le_bytes(bytes.try_into()?))
428 }
429 PrimitiveType::Timestamptz => {
430 PrimitiveLiteral::Long(i64::from_le_bytes(bytes.try_into()?))
431 }
432 PrimitiveType::TimestampNs => {
433 PrimitiveLiteral::Long(i64::from_le_bytes(bytes.try_into()?))
434 }
435 PrimitiveType::TimestamptzNs => {
436 PrimitiveLiteral::Long(i64::from_le_bytes(bytes.try_into()?))
437 }
438 PrimitiveType::String => {
439 PrimitiveLiteral::String(std::str::from_utf8(bytes)?.to_string())
440 }
441 PrimitiveType::Uuid => {
442 PrimitiveLiteral::UInt128(u128::from_be_bytes(bytes.try_into()?))
443 }
444 PrimitiveType::Fixed(_)
445 | PrimitiveType::Binary
446 | PrimitiveType::Geometry(_)
447 | PrimitiveType::Geography(_) => PrimitiveLiteral::Binary(Vec::from(bytes)),
448 PrimitiveType::Decimal { .. } => PrimitiveLiteral::Int128(
449 i128_from_be_bytes(bytes)
450 .ok_or_else(|| invalid_data!("Can't convert bytes to i128: {bytes:?}"))?,
451 ),
452 };
453 Ok(Datum::new(data_type, literal))
454 }
455
456 pub fn to_bytes(&self) -> Result<ByteBuf> {
460 let buf = match &self.literal {
461 PrimitiveLiteral::Boolean(val) => {
462 if *val {
463 ByteBuf::from([1u8])
464 } else {
465 ByteBuf::from([0u8])
466 }
467 }
468 PrimitiveLiteral::Int(val) => ByteBuf::from(val.to_le_bytes()),
469 PrimitiveLiteral::Long(val) => ByteBuf::from(val.to_le_bytes()),
470 PrimitiveLiteral::Float(val) => ByteBuf::from(val.to_le_bytes()),
471 PrimitiveLiteral::Double(val) => ByteBuf::from(val.to_le_bytes()),
472 PrimitiveLiteral::String(val) => ByteBuf::from(val.as_bytes()),
473 PrimitiveLiteral::UInt128(val) => ByteBuf::from(val.to_be_bytes()),
474 PrimitiveLiteral::Binary(val) => ByteBuf::from(val.as_slice()),
475 PrimitiveLiteral::Int128(val) => {
476 let PrimitiveType::Decimal { precision, .. } = self.r#type else {
477 return Err(invalid_data!(
478 "PrimitiveLiteral Int128 must be PrimitiveType Decimal but got {}",
479 self.r#type
480 ));
481 };
482
483 let Ok(required_bytes) = Type::decimal_required_bytes(precision) else {
486 return Err(invalid_data!(
487 "PrimitiveType Decimal must has valid precision but got {precision}"
488 ));
489 };
490
491 let mut bytes = i128_to_be_bytes_min(*val);
494 bytes.truncate(required_bytes as usize);
496
497 ByteBuf::from(bytes)
498 }
499 PrimitiveLiteral::AboveMax | PrimitiveLiteral::BelowMin => {
500 return Err(invalid_data!(
501 "Cannot convert AboveMax or BelowMin to bytes"
502 ));
503 }
504 };
505
506 Ok(buf)
507 }
508
509 pub fn bool<T: Into<bool>>(t: T) -> Self {
523 Self {
524 r#type: PrimitiveType::Boolean,
525 literal: PrimitiveLiteral::Boolean(t.into()),
526 }
527 }
528
529 pub fn bool_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
544 let v = s
545 .as_ref()
546 .parse::<bool>()
547 .map_err(|e| invalid_data!("Can't parse string to bool.").with_source(e))?;
548 Ok(Self::bool(v))
549 }
550
551 pub fn int<T: Into<i32>>(t: T) -> Self {
562 Self {
563 r#type: PrimitiveType::Int,
564 literal: PrimitiveLiteral::Int(t.into()),
565 }
566 }
567
568 pub fn long<T: Into<i64>>(t: T) -> Self {
579 Self {
580 r#type: PrimitiveType::Long,
581 literal: PrimitiveLiteral::Long(t.into()),
582 }
583 }
584
585 pub fn float<T: Into<f32>>(t: T) -> Self {
600 Self {
601 r#type: PrimitiveType::Float,
602 literal: PrimitiveLiteral::Float(OrderedFloat(t.into())),
603 }
604 }
605
606 pub fn double<T: Into<f64>>(t: T) -> Self {
621 Self {
622 r#type: PrimitiveType::Double,
623 literal: PrimitiveLiteral::Double(OrderedFloat(t.into())),
624 }
625 }
626
627 pub fn date(days: i32) -> Self {
639 Self {
640 r#type: PrimitiveType::Date,
641 literal: PrimitiveLiteral::Int(days),
642 }
643 }
644
645 pub fn date_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
658 let t = s.as_ref().parse::<NaiveDate>().map_err(|e| {
659 invalid_data!("Can't parse date from string: {}", s.as_ref()).with_source(e)
660 })?;
661
662 Ok(Self::date(date::date_from_naive_date(t)))
663 }
664
665 pub fn date_from_ymd(year: i32, month: u32, day: u32) -> Result<Self> {
679 let t = NaiveDate::from_ymd_opt(year, month, day).ok_or_else(|| {
680 invalid_data!("Can't create date from year: {year}, month: {month}, day: {day}")
681 })?;
682
683 Ok(Self::date(date::date_from_naive_date(t)))
684 }
685
686 pub fn time_micros(value: i64) -> Result<Self> {
713 ensure_data_valid!(
714 (0..=MAX_TIME_VALUE).contains(&value),
715 "Invalid value for Time type: {}",
716 value
717 );
718
719 Ok(Self {
720 r#type: PrimitiveType::Time,
721 literal: PrimitiveLiteral::Long(value),
722 })
723 }
724
725 fn time_from_naive_time(t: NaiveTime) -> Self {
727 let duration = t - date::unix_epoch().time();
728 let micro_secs = duration.num_microseconds().unwrap();
730
731 Self {
732 r#type: PrimitiveType::Time,
733 literal: PrimitiveLiteral::Long(micro_secs),
734 }
735 }
736
737 pub fn time_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
749 let t = s.as_ref().parse::<NaiveTime>().map_err(|e| {
750 invalid_data!("Can't parse time from string: {}", s.as_ref()).with_source(e)
751 })?;
752
753 Ok(Self::time_from_naive_time(t))
754 }
755
756 pub fn time_from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> Result<Self> {
768 let t = NaiveTime::from_hms_micro_opt(hour, min, sec, micro)
769 .ok_or_else(|| invalid_data!("Can't create time from hour: {hour}, min: {min}, second: {sec}, microsecond: {micro}"))?;
770 Ok(Self::time_from_naive_time(t))
771 }
772
773 pub fn timestamp_micros(value: i64) -> Self {
784 Self {
785 r#type: PrimitiveType::Timestamp,
786 literal: PrimitiveLiteral::Long(value),
787 }
788 }
789
790 pub fn timestamp_nanos(value: i64) -> Self {
801 Self {
802 r#type: PrimitiveType::TimestampNs,
803 literal: PrimitiveLiteral::Long(value),
804 }
805 }
806
807 pub fn timestamp_from_datetime(dt: NaiveDateTime) -> Self {
824 Self::timestamp_micros(dt.and_utc().timestamp_micros())
825 }
826
827 pub fn timestamp_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
841 let dt = s
842 .as_ref()
843 .parse::<NaiveDateTime>()
844 .map_err(|e| invalid_data!("Can't parse timestamp.").with_source(e))?;
845
846 Ok(Self::timestamp_from_datetime(dt))
847 }
848
849 pub fn timestamptz_micros(value: i64) -> Self {
860 Self {
861 r#type: PrimitiveType::Timestamptz,
862 literal: PrimitiveLiteral::Long(value),
863 }
864 }
865
866 pub fn timestamptz_nanos(value: i64) -> Self {
877 Self {
878 r#type: PrimitiveType::TimestamptzNs,
879 literal: PrimitiveLiteral::Long(value),
880 }
881 }
882
883 pub fn timestamptz_from_datetime<T: TimeZone>(dt: DateTime<T>) -> Self {
894 Self::timestamptz_micros(dt.with_timezone(&Utc).timestamp_micros())
895 }
896
897 pub fn timestamptz_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
911 let dt = DateTime::<Utc>::from_str(s.as_ref())
912 .map_err(|e| invalid_data!("Can't parse datetime.").with_source(e))?;
913
914 Ok(Self::timestamptz_from_datetime(dt))
915 }
916
917 pub fn string<S: ToString>(s: S) -> Self {
928 Self {
929 r#type: PrimitiveType::String,
930 literal: PrimitiveLiteral::String(s.to_string()),
931 }
932 }
933
934 pub fn uuid(uuid: uuid::Uuid) -> Self {
946 Self {
947 r#type: PrimitiveType::Uuid,
948 literal: PrimitiveLiteral::UInt128(uuid.as_u128()),
949 }
950 }
951
952 pub fn uuid_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
963 let uuid = uuid::Uuid::parse_str(s.as_ref()).map_err(|e| {
964 invalid_data!("Can't parse uuid from string: {}", s.as_ref()).with_source(e)
965 })?;
966 Ok(Self::uuid(uuid))
967 }
968
969 pub fn fixed<I: IntoIterator<Item = u8>>(input: I) -> Self {
980 let value: Vec<u8> = input.into_iter().collect();
981 Self {
982 r#type: PrimitiveType::Fixed(value.len() as u64),
983 literal: PrimitiveLiteral::Binary(value),
984 }
985 }
986
987 pub fn binary<I: IntoIterator<Item = u8>>(input: I) -> Self {
998 Self {
999 r#type: PrimitiveType::Binary,
1000 literal: PrimitiveLiteral::Binary(input.into_iter().collect()),
1001 }
1002 }
1003
1004 pub fn decimal_from_str<S: AsRef<str>>(s: S) -> Result<Self> {
1015 let decimal = decimal_from_str_exact(s.as_ref())?;
1016
1017 Self::decimal(decimal)
1018 }
1019
1020 pub fn decimal(value: Decimal) -> Result<Self> {
1032 let scale = decimal_scale(&value);
1033
1034 let r#type = Type::decimal(MAX_DECIMAL_PRECISION, scale)?;
1035 if let Type::Primitive(p) = r#type {
1036 Ok(Self {
1037 r#type: p,
1038 literal: PrimitiveLiteral::Int128(decimal_mantissa(&value)),
1039 })
1040 } else {
1041 unreachable!("Decimal type must be primitive.")
1042 }
1043 }
1044
1045 pub fn decimal_with_precision(value: Decimal, precision: u32) -> Result<Self> {
1051 let scale = decimal_scale(&value);
1052 let mantissa = decimal_mantissa(&value);
1053
1054 Self::decimal_from_mantissa(mantissa, precision, scale)
1055 }
1056
1057 fn i64_to_i32<T: Into<i64> + PartialOrd<i64>>(val: T) -> Datum {
1058 if val > INT_MAX as i64 {
1059 Datum::new(PrimitiveType::Int, PrimitiveLiteral::AboveMax)
1060 } else if val < INT_MIN as i64 {
1061 Datum::new(PrimitiveType::Int, PrimitiveLiteral::BelowMin)
1062 } else {
1063 Datum::int(val.into() as i32)
1064 }
1065 }
1066
1067 fn i128_to_i32<T: Into<i128> + PartialOrd<i128>>(val: T) -> Datum {
1068 if val > INT_MAX as i128 {
1069 Datum::new(PrimitiveType::Int, PrimitiveLiteral::AboveMax)
1070 } else if val < INT_MIN as i128 {
1071 Datum::new(PrimitiveType::Int, PrimitiveLiteral::BelowMin)
1072 } else {
1073 Datum::int(val.into() as i32)
1074 }
1075 }
1076
1077 fn i128_to_i64<T: Into<i128> + PartialOrd<i128>>(val: T) -> Datum {
1078 if val > LONG_MAX as i128 {
1079 Datum::new(PrimitiveType::Long, PrimitiveLiteral::AboveMax)
1080 } else if val < LONG_MIN as i128 {
1081 Datum::new(PrimitiveType::Long, PrimitiveLiteral::BelowMin)
1082 } else {
1083 Datum::long(val.into() as i64)
1084 }
1085 }
1086
1087 fn f64_to_f32(val: f64) -> Datum {
1088 if val > f32::MAX as f64 {
1089 Datum::new(PrimitiveType::Float, PrimitiveLiteral::AboveMax)
1090 } else if val < (f32::MIN as f64) {
1091 Datum::new(PrimitiveType::Float, PrimitiveLiteral::BelowMin)
1092 } else {
1093 Datum::float(val as f32)
1094 }
1095 }
1096
1097 fn string_to_i128<S: AsRef<str>>(s: S) -> Result<i128> {
1098 s.as_ref()
1099 .parse::<i128>()
1100 .map_err(|e| invalid_data!("Can't parse string to i128.").with_source(e))
1101 }
1102
1103 fn decimal_from_mantissa(mantissa: i128, precision: u32, scale: u32) -> Result<Self> {
1104 let r#type = Type::decimal(precision, scale)?;
1105 if decimal_precision(mantissa) > precision {
1106 let value = decimal_from_i128_with_scale(mantissa, scale);
1107 return Err(invalid_data!(
1108 "Decimal value {value} is too large for precision {precision}"
1109 ));
1110 }
1111
1112 if let Type::Primitive(p) = r#type {
1113 Ok(Self {
1114 r#type: p,
1115 literal: PrimitiveLiteral::Int128(mantissa),
1116 })
1117 } else {
1118 unreachable!("Decimal type must be primitive.")
1119 }
1120 }
1121
1122 pub(crate) fn with_decimal_mantissa(&self, mantissa: i128) -> Result<Self> {
1127 ensure_data_valid!(
1128 matches!(self.r#type, PrimitiveType::Decimal { .. }),
1129 "Expected a decimal datum, got: {:?}",
1130 self.r#type
1131 );
1132 Ok(Self::new(
1133 self.r#type.clone(),
1134 PrimitiveLiteral::Int128(mantissa),
1135 ))
1136 }
1137
1138 pub fn to(self, target_type: &Type) -> Result<Datum> {
1140 match target_type {
1141 Type::Primitive(target_primitive_type) => {
1142 match (&self.literal, &self.r#type, target_primitive_type) {
1143 (PrimitiveLiteral::Int(val), _, PrimitiveType::Int) => Ok(Datum::int(*val)),
1144 (PrimitiveLiteral::Int(val), _, PrimitiveType::Date) => Ok(Datum::date(*val)),
1145 (PrimitiveLiteral::Int(val), _, PrimitiveType::Long) => Ok(Datum::long(*val)),
1146 (PrimitiveLiteral::Long(val), _, PrimitiveType::Int) => {
1147 Ok(Datum::i64_to_i32(*val))
1148 }
1149 (PrimitiveLiteral::Double(val), _, PrimitiveType::Float) => {
1150 Ok(Datum::f64_to_f32(val.0))
1151 }
1152 (PrimitiveLiteral::Float(val), _, PrimitiveType::Double) => {
1153 Ok(Datum::double(val.0 as f64))
1154 }
1155 (PrimitiveLiteral::Long(val), _, PrimitiveType::Timestamp) => {
1156 Ok(Datum::timestamp_micros(*val))
1157 }
1158 (PrimitiveLiteral::Long(val), _, PrimitiveType::Timestamptz) => {
1159 Ok(Datum::timestamptz_micros(*val))
1160 }
1161 (PrimitiveLiteral::Int128(val), _, PrimitiveType::Long) => {
1163 Ok(Datum::i128_to_i64(*val))
1164 }
1165 (
1166 PrimitiveLiteral::Int128(val),
1167 PrimitiveType::Decimal {
1168 scale: self_scale, ..
1169 },
1170 PrimitiveType::Decimal {
1171 precision,
1172 scale: target_scale,
1173 },
1174 ) if self_scale == target_scale => {
1175 Datum::decimal_from_mantissa(*val, *precision, *target_scale)
1176 }
1177 (
1182 PrimitiveLiteral::Int128(_),
1183 PrimitiveType::Decimal {
1184 scale: self_scale, ..
1185 },
1186 PrimitiveType::Decimal {
1187 scale: target_scale,
1188 ..
1189 },
1190 ) => Err(invalid_data!(
1191 "Decimal scale conversion is not supported: source scale {self_scale}, target scale {target_scale}"
1192 )),
1193 (PrimitiveLiteral::String(val), _, PrimitiveType::Boolean) => {
1194 Datum::bool_from_str(val)
1195 }
1196 (PrimitiveLiteral::String(val), _, PrimitiveType::Int) => {
1197 Datum::string_to_i128(val).map(Datum::i128_to_i32)
1198 }
1199 (PrimitiveLiteral::String(val), _, PrimitiveType::Long) => {
1200 Datum::string_to_i128(val).map(Datum::i128_to_i64)
1201 }
1202 (PrimitiveLiteral::String(val), _, PrimitiveType::Timestamp) => {
1203 Datum::timestamp_from_str(val)
1204 }
1205 (PrimitiveLiteral::String(val), _, PrimitiveType::Timestamptz) => {
1206 Datum::timestamptz_from_str(val)
1207 }
1208
1209 (_, self_type, target_type) if self_type == target_type => Ok(self),
1211 _ => Err(invalid_data!(
1212 "Can't convert datum from {} type to {} type.",
1213 self.r#type,
1214 target_primitive_type
1215 )),
1216 }
1217 }
1218 _ => Err(invalid_data!(
1219 "Can't convert datum from {} type to {} type.",
1220 self.r#type,
1221 target_type
1222 )),
1223 }
1224 }
1225
1226 pub fn literal(&self) -> &PrimitiveLiteral {
1228 &self.literal
1229 }
1230
1231 pub fn data_type(&self) -> &PrimitiveType {
1233 &self.r#type
1234 }
1235
1236 pub(crate) fn promote_to(&self, target: &PrimitiveType) -> Option<Datum> {
1242 self.literal
1243 .promote_to(target)
1244 .map(|literal| Datum::new(target.clone(), literal))
1245 }
1246
1247 pub fn is_nan(&self) -> bool {
1250 match self.literal {
1251 PrimitiveLiteral::Double(val) => val.is_nan(),
1252 PrimitiveLiteral::Float(val) => val.is_nan(),
1253 _ => false,
1254 }
1255 }
1256
1257 pub fn to_human_string(&self) -> String {
1264 match self.literal() {
1265 PrimitiveLiteral::String(s) => s.to_string(),
1266 PrimitiveLiteral::Float(val) => human_float(val.0),
1267 PrimitiveLiteral::Double(val) => human_float(val.0),
1268 _ => self.to_string(),
1269 }
1270 }
1271}
1272
1273fn human_float<T: Float + LowerExp + FromStr>(value: T) -> String {
1277 if value.is_nan() {
1278 return "NaN".to_string();
1279 }
1280 let sign = if value.is_sign_negative() { "-" } else { "" };
1281 if value.is_infinite() {
1282 return format!("{sign}Infinity");
1283 }
1284 if value.is_zero() {
1285 return format!("{sign}0.0");
1286 }
1287
1288 let abs = value.abs();
1289 let shortest = format!("{abs:e}");
1294 let precision = shortest.find('e').unwrap().saturating_sub(2).max(1);
1295 let closest = format!("{abs:.precision$e}");
1296 let scientific = if closest.parse::<T>().is_ok_and(|v| v == abs) {
1297 closest
1298 } else {
1299 shortest
1300 };
1301 let (mantissa, exponent) = scientific.split_once('e').unwrap();
1302 let exponent: i32 = exponent.parse().unwrap();
1303 let digits = mantissa.replace('.', "");
1304 let digits = digits.trim_end_matches('0');
1305
1306 if (-3..7).contains(&exponent) {
1307 if exponent < 0 {
1308 let zeros = "0".repeat((-exponent - 1) as usize);
1309 format!("{sign}0.{zeros}{digits}")
1310 } else {
1311 let int_len = exponent as usize + 1;
1312 if digits.len() > int_len {
1313 format!("{sign}{}.{}", &digits[..int_len], &digits[int_len..])
1314 } else {
1315 format!("{sign}{digits:0<int_len$}.0")
1316 }
1317 }
1318 } else {
1319 let fraction = if digits.len() > 1 { &digits[1..] } else { "0" };
1320 format!("{sign}{}.{fraction}E{exponent}", &digits[..1])
1321 }
1322}