1use crate::delta::{
21 add_days_datetime, add_months_date, add_months_datetime, sub_days_datetime, sub_months_datetime,
22};
23use crate::temporal_conversions::as_datetime_with_timezone;
24use crate::timezone::Tz;
25use crate::{ArrowNativeTypeOp, OffsetSizeTrait};
26use arrow_buffer::{Buffer, OffsetBuffer, i256};
27use arrow_data::decimal::{
28 format_decimal_str, is_validate_decimal_precision, is_validate_decimal32_precision,
29 is_validate_decimal64_precision, is_validate_decimal256_precision, validate_decimal_precision,
30 validate_decimal32_precision, validate_decimal64_precision, validate_decimal256_precision,
31};
32use arrow_data::{validate_binary_view, validate_string_view};
33use arrow_schema::{
34 ArrowError, DECIMAL_DEFAULT_SCALE, DECIMAL32_DEFAULT_SCALE, DECIMAL32_MAX_PRECISION,
35 DECIMAL32_MAX_SCALE, DECIMAL64_DEFAULT_SCALE, DECIMAL64_MAX_PRECISION, DECIMAL64_MAX_SCALE,
36 DECIMAL128_MAX_PRECISION, DECIMAL128_MAX_SCALE, DECIMAL256_MAX_PRECISION, DECIMAL256_MAX_SCALE,
37 DataType, IntervalUnit, TimeUnit,
38};
39use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, TimeZone};
40use half::f16;
41use std::fmt::Debug;
42use std::marker::PhantomData;
43use std::ops::Sub;
44
45pub use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
47
48#[derive(Debug)]
52pub struct BooleanType {}
53
54impl BooleanType {
55 pub const DATA_TYPE: DataType = DataType::Boolean;
57}
58
59pub trait ArrowPrimitiveType: primitive::PrimitiveTypeSealed + 'static {
68 type Native: ArrowNativeTypeOp;
70
71 const DATA_TYPE: DataType;
73
74 fn default_value() -> Self::Native {
78 Default::default()
79 }
80}
81
82mod primitive {
83 pub trait PrimitiveTypeSealed {}
84}
85
86macro_rules! make_type {
87 ($name:ident, $native_ty:ty, $data_ty:expr, $doc_string: literal) => {
88 #[derive(Debug)]
89 #[doc = $doc_string]
90 pub struct $name {}
91
92 impl ArrowPrimitiveType for $name {
93 type Native = $native_ty;
94 const DATA_TYPE: DataType = $data_ty;
95 }
96
97 impl primitive::PrimitiveTypeSealed for $name {}
98 };
99}
100
101make_type!(Int8Type, i8, DataType::Int8, "A signed 8-bit integer type.");
102make_type!(
103 Int16Type,
104 i16,
105 DataType::Int16,
106 "Signed 16-bit integer type."
107);
108make_type!(
109 Int32Type,
110 i32,
111 DataType::Int32,
112 "Signed 32-bit integer type."
113);
114make_type!(
115 Int64Type,
116 i64,
117 DataType::Int64,
118 "Signed 64-bit integer type."
119);
120make_type!(
121 UInt8Type,
122 u8,
123 DataType::UInt8,
124 "Unsigned 8-bit integer type."
125);
126make_type!(
127 UInt16Type,
128 u16,
129 DataType::UInt16,
130 "Unsigned 16-bit integer type."
131);
132make_type!(
133 UInt32Type,
134 u32,
135 DataType::UInt32,
136 "Unsigned 32-bit integer type."
137);
138make_type!(
139 UInt64Type,
140 u64,
141 DataType::UInt64,
142 "Unsigned 64-bit integer type."
143);
144make_type!(
145 Float16Type,
146 f16,
147 DataType::Float16,
148 "16-bit floating point number type."
149);
150make_type!(
151 Float32Type,
152 f32,
153 DataType::Float32,
154 "32-bit floating point number type."
155);
156make_type!(
157 Float64Type,
158 f64,
159 DataType::Float64,
160 "64-bit floating point number type."
161);
162make_type!(
163 TimestampSecondType,
164 i64,
165 DataType::Timestamp(TimeUnit::Second, None),
166 "Timestamp second type with an optional timezone."
167);
168make_type!(
169 TimestampMillisecondType,
170 i64,
171 DataType::Timestamp(TimeUnit::Millisecond, None),
172 "Timestamp millisecond type with an optional timezone."
173);
174make_type!(
175 TimestampMicrosecondType,
176 i64,
177 DataType::Timestamp(TimeUnit::Microsecond, None),
178 "Timestamp microsecond type with an optional timezone."
179);
180make_type!(
181 TimestampNanosecondType,
182 i64,
183 DataType::Timestamp(TimeUnit::Nanosecond, None),
184 "Timestamp nanosecond type with an optional timezone."
185);
186make_type!(
187 Date32Type,
188 i32,
189 DataType::Date32,
190 "32-bit date type: the elapsed time since UNIX epoch in days (32 bits)."
191);
192make_type!(
193 Date64Type,
194 i64,
195 DataType::Date64,
196 "64-bit date type: the elapsed time since UNIX epoch in milliseconds (64 bits). \
197 Values must be divisible by `86_400_000`. \
198 See [`DataType::Date64`] for more details."
199);
200make_type!(
201 Time32SecondType,
202 i32,
203 DataType::Time32(TimeUnit::Second),
204 "32-bit time type: the elapsed time since midnight in seconds."
205);
206make_type!(
207 Time32MillisecondType,
208 i32,
209 DataType::Time32(TimeUnit::Millisecond),
210 "32-bit time type: the elapsed time since midnight in milliseconds."
211);
212make_type!(
213 Time64MicrosecondType,
214 i64,
215 DataType::Time64(TimeUnit::Microsecond),
216 "64-bit time type: the elapsed time since midnight in microseconds."
217);
218make_type!(
219 Time64NanosecondType,
220 i64,
221 DataType::Time64(TimeUnit::Nanosecond),
222 "64-bit time type: the elapsed time since midnight in nanoseconds."
223);
224make_type!(
225 IntervalYearMonthType,
226 i32,
227 DataType::Interval(IntervalUnit::YearMonth),
228 "32-bit “calendar” interval type: the number of whole months."
229);
230make_type!(
231 IntervalDayTimeType,
232 IntervalDayTime,
233 DataType::Interval(IntervalUnit::DayTime),
234 "“Calendar” interval type: days and milliseconds. See [`IntervalDayTime`] for more details."
235);
236make_type!(
237 IntervalMonthDayNanoType,
238 IntervalMonthDayNano,
239 DataType::Interval(IntervalUnit::MonthDayNano),
240 r"“Calendar” interval type: months, days, and nanoseconds. See [`IntervalMonthDayNano`] for more details."
241);
242make_type!(
243 DurationSecondType,
244 i64,
245 DataType::Duration(TimeUnit::Second),
246 "Elapsed time type: seconds."
247);
248make_type!(
249 DurationMillisecondType,
250 i64,
251 DataType::Duration(TimeUnit::Millisecond),
252 "Elapsed time type: milliseconds."
253);
254make_type!(
255 DurationMicrosecondType,
256 i64,
257 DataType::Duration(TimeUnit::Microsecond),
258 "Elapsed time type: microseconds."
259);
260make_type!(
261 DurationNanosecondType,
262 i64,
263 DataType::Duration(TimeUnit::Nanosecond),
264 "Elapsed time type: nanoseconds."
265);
266
267pub trait ArrowDictionaryKeyType: ArrowPrimitiveType {}
270
271impl ArrowDictionaryKeyType for Int8Type {}
272
273impl ArrowDictionaryKeyType for Int16Type {}
274
275impl ArrowDictionaryKeyType for Int32Type {}
276
277impl ArrowDictionaryKeyType for Int64Type {}
278
279impl ArrowDictionaryKeyType for UInt8Type {}
280
281impl ArrowDictionaryKeyType for UInt16Type {}
282
283impl ArrowDictionaryKeyType for UInt32Type {}
284
285impl ArrowDictionaryKeyType for UInt64Type {}
286
287pub trait RunEndIndexType: ArrowPrimitiveType {}
291
292impl RunEndIndexType for Int16Type {}
293
294impl RunEndIndexType for Int32Type {}
295
296impl RunEndIndexType for Int64Type {}
297
298pub trait ArrowTemporalType: ArrowPrimitiveType {}
300
301impl ArrowTemporalType for TimestampSecondType {}
302impl ArrowTemporalType for TimestampMillisecondType {}
303impl ArrowTemporalType for TimestampMicrosecondType {}
304impl ArrowTemporalType for TimestampNanosecondType {}
305impl ArrowTemporalType for Date32Type {}
306impl ArrowTemporalType for Date64Type {}
307impl ArrowTemporalType for Time32SecondType {}
308impl ArrowTemporalType for Time32MillisecondType {}
309impl ArrowTemporalType for Time64MicrosecondType {}
310impl ArrowTemporalType for Time64NanosecondType {}
311impl ArrowTemporalType for DurationSecondType {}
315impl ArrowTemporalType for DurationMillisecondType {}
316impl ArrowTemporalType for DurationMicrosecondType {}
317impl ArrowTemporalType for DurationNanosecondType {}
318
319pub trait ArrowTimestampType: ArrowTemporalType<Native = i64> {
321 const UNIT: TimeUnit;
323
324 #[deprecated(since = "58.1.0", note = "Use from_naive_datetime instead")]
328 fn make_value(naive: NaiveDateTime) -> Option<i64>;
329
330 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64>;
339
340 fn from_naive_datetime(naive: NaiveDateTime, tz: Option<&Tz>) -> Option<i64> {
348 match tz {
349 Some(tz) => match tz.from_local_datetime(&naive) {
350 chrono::offset::LocalResult::Single(dt) => Self::from_datetime(dt),
351 chrono::offset::LocalResult::Ambiguous(dt1, _) => Self::from_datetime(dt1),
352 chrono::offset::LocalResult::None => None,
353 },
354 None => Self::from_datetime(naive.and_utc()),
355 }
356 }
357}
358
359impl ArrowTimestampType for TimestampSecondType {
360 const UNIT: TimeUnit = TimeUnit::Second;
361
362 fn make_value(naive: NaiveDateTime) -> Option<i64> {
363 Some(naive.and_utc().timestamp())
364 }
365
366 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
367 Some(datetime.timestamp())
368 }
369}
370impl ArrowTimestampType for TimestampMillisecondType {
371 const UNIT: TimeUnit = TimeUnit::Millisecond;
372
373 fn make_value(naive: NaiveDateTime) -> Option<i64> {
374 let utc = naive.and_utc();
375 let millis = utc.timestamp().checked_mul(1_000)?;
376 millis.checked_add(utc.timestamp_subsec_millis() as i64)
377 }
378
379 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
380 let millis = datetime.timestamp().checked_mul(1_000)?;
381 millis.checked_add(datetime.timestamp_subsec_millis() as i64)
382 }
383}
384impl ArrowTimestampType for TimestampMicrosecondType {
385 const UNIT: TimeUnit = TimeUnit::Microsecond;
386
387 fn make_value(naive: NaiveDateTime) -> Option<i64> {
388 let utc = naive.and_utc();
389 let micros = utc.timestamp().checked_mul(1_000_000)?;
390 micros.checked_add(utc.timestamp_subsec_micros() as i64)
391 }
392
393 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
394 let micros = datetime.timestamp().checked_mul(1_000_000)?;
395 micros.checked_add(datetime.timestamp_subsec_micros() as i64)
396 }
397}
398impl ArrowTimestampType for TimestampNanosecondType {
399 const UNIT: TimeUnit = TimeUnit::Nanosecond;
400
401 fn make_value(naive: NaiveDateTime) -> Option<i64> {
402 let utc = naive.and_utc();
403 let nanos = utc.timestamp().checked_mul(1_000_000_000)?;
404 nanos.checked_add(utc.timestamp_subsec_nanos() as i64)
405 }
406
407 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
408 datetime.timestamp_nanos_opt()
409 }
410}
411
412fn add_year_months<T: ArrowTimestampType>(
413 timestamp: <T as ArrowPrimitiveType>::Native,
414 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
415 tz: Tz,
416) -> Option<<T as ArrowPrimitiveType>::Native> {
417 let months = IntervalYearMonthType::to_months(delta);
418 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
419 let res = add_months_datetime(res, months)?;
420 T::from_naive_datetime(res.naive_utc(), None)
421}
422
423fn add_day_time<T: ArrowTimestampType>(
424 timestamp: <T as ArrowPrimitiveType>::Native,
425 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
426 tz: Tz,
427) -> Option<<T as ArrowPrimitiveType>::Native> {
428 let (days, ms) = IntervalDayTimeType::to_parts(delta);
429 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
430 let res = add_days_datetime(res, days)?;
431 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
432 T::from_naive_datetime(res.naive_utc(), None)
433}
434
435fn add_month_day_nano<T: ArrowTimestampType>(
436 timestamp: <T as ArrowPrimitiveType>::Native,
437 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
438 tz: Tz,
439) -> Option<<T as ArrowPrimitiveType>::Native> {
440 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
441 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
442 let res = add_months_datetime(res, months)?;
443 let res = add_days_datetime(res, days)?;
444 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
445 T::from_naive_datetime(res.naive_utc(), None)
446}
447
448fn subtract_year_months<T: ArrowTimestampType>(
449 timestamp: <T as ArrowPrimitiveType>::Native,
450 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
451 tz: Tz,
452) -> Option<<T as ArrowPrimitiveType>::Native> {
453 let months = IntervalYearMonthType::to_months(delta);
454 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
455 let res = sub_months_datetime(res, months)?;
456 T::from_naive_datetime(res.naive_utc(), None)
457}
458
459fn subtract_day_time<T: ArrowTimestampType>(
460 timestamp: <T as ArrowPrimitiveType>::Native,
461 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
462 tz: Tz,
463) -> Option<<T as ArrowPrimitiveType>::Native> {
464 let (days, ms) = IntervalDayTimeType::to_parts(delta);
465 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
466 let res = sub_days_datetime(res, days)?;
467 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
468 T::from_naive_datetime(res.naive_utc(), None)
469}
470
471fn subtract_month_day_nano<T: ArrowTimestampType>(
472 timestamp: <T as ArrowPrimitiveType>::Native,
473 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
474 tz: Tz,
475) -> Option<<T as ArrowPrimitiveType>::Native> {
476 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
477 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
478 let res = sub_months_datetime(res, months)?;
479 let res = sub_days_datetime(res, days)?;
480 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
481 T::from_naive_datetime(res.naive_utc(), None)
482}
483
484impl TimestampSecondType {
485 pub fn add_year_months(
495 timestamp: <Self as ArrowPrimitiveType>::Native,
496 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
497 tz: Tz,
498 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
499 add_year_months::<Self>(timestamp, delta, tz)
500 }
501
502 pub fn add_day_time(
512 timestamp: <Self as ArrowPrimitiveType>::Native,
513 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
514 tz: Tz,
515 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
516 add_day_time::<Self>(timestamp, delta, tz)
517 }
518
519 pub fn add_month_day_nano(
528 timestamp: <Self as ArrowPrimitiveType>::Native,
529 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
530 tz: Tz,
531 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
532 add_month_day_nano::<Self>(timestamp, delta, tz)
533 }
534
535 pub fn subtract_year_months(
545 timestamp: <Self as ArrowPrimitiveType>::Native,
546 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
547 tz: Tz,
548 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
549 subtract_year_months::<Self>(timestamp, delta, tz)
550 }
551
552 pub fn subtract_day_time(
562 timestamp: <Self as ArrowPrimitiveType>::Native,
563 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
564 tz: Tz,
565 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
566 subtract_day_time::<Self>(timestamp, delta, tz)
567 }
568
569 pub fn subtract_month_day_nano(
579 timestamp: <Self as ArrowPrimitiveType>::Native,
580 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
581 tz: Tz,
582 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
583 subtract_month_day_nano::<Self>(timestamp, delta, tz)
584 }
585}
586
587impl TimestampMicrosecondType {
588 pub fn add_year_months(
596 timestamp: <Self as ArrowPrimitiveType>::Native,
597 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
598 tz: Tz,
599 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
600 add_year_months::<Self>(timestamp, delta, tz)
601 }
602
603 pub fn add_day_time(
611 timestamp: <Self as ArrowPrimitiveType>::Native,
612 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
613 tz: Tz,
614 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
615 add_day_time::<Self>(timestamp, delta, tz)
616 }
617
618 pub fn add_month_day_nano(
626 timestamp: <Self as ArrowPrimitiveType>::Native,
627 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
628 tz: Tz,
629 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
630 add_month_day_nano::<Self>(timestamp, delta, tz)
631 }
632
633 pub fn subtract_year_months(
641 timestamp: <Self as ArrowPrimitiveType>::Native,
642 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
643 tz: Tz,
644 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
645 subtract_year_months::<Self>(timestamp, delta, tz)
646 }
647
648 pub fn subtract_day_time(
656 timestamp: <Self as ArrowPrimitiveType>::Native,
657 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
658 tz: Tz,
659 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
660 subtract_day_time::<Self>(timestamp, delta, tz)
661 }
662
663 pub fn subtract_month_day_nano(
671 timestamp: <Self as ArrowPrimitiveType>::Native,
672 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
673 tz: Tz,
674 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
675 subtract_month_day_nano::<Self>(timestamp, delta, tz)
676 }
677}
678
679impl TimestampMillisecondType {
680 pub fn add_year_months(
688 timestamp: <Self as ArrowPrimitiveType>::Native,
689 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
690 tz: Tz,
691 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
692 add_year_months::<Self>(timestamp, delta, tz)
693 }
694
695 pub fn add_day_time(
703 timestamp: <Self as ArrowPrimitiveType>::Native,
704 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
705 tz: Tz,
706 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
707 add_day_time::<Self>(timestamp, delta, tz)
708 }
709
710 pub fn add_month_day_nano(
718 timestamp: <Self as ArrowPrimitiveType>::Native,
719 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
720 tz: Tz,
721 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
722 add_month_day_nano::<Self>(timestamp, delta, tz)
723 }
724
725 pub fn subtract_year_months(
733 timestamp: <Self as ArrowPrimitiveType>::Native,
734 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
735 tz: Tz,
736 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
737 subtract_year_months::<Self>(timestamp, delta, tz)
738 }
739
740 pub fn subtract_day_time(
748 timestamp: <Self as ArrowPrimitiveType>::Native,
749 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
750 tz: Tz,
751 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
752 subtract_day_time::<Self>(timestamp, delta, tz)
753 }
754
755 pub fn subtract_month_day_nano(
763 timestamp: <Self as ArrowPrimitiveType>::Native,
764 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
765 tz: Tz,
766 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
767 subtract_month_day_nano::<Self>(timestamp, delta, tz)
768 }
769}
770
771impl TimestampNanosecondType {
772 pub fn add_year_months(
780 timestamp: <Self as ArrowPrimitiveType>::Native,
781 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
782 tz: Tz,
783 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
784 add_year_months::<Self>(timestamp, delta, tz)
785 }
786
787 pub fn add_day_time(
795 timestamp: <Self as ArrowPrimitiveType>::Native,
796 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
797 tz: Tz,
798 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
799 add_day_time::<Self>(timestamp, delta, tz)
800 }
801
802 pub fn add_month_day_nano(
810 timestamp: <Self as ArrowPrimitiveType>::Native,
811 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
812 tz: Tz,
813 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
814 add_month_day_nano::<Self>(timestamp, delta, tz)
815 }
816
817 pub fn subtract_year_months(
825 timestamp: <Self as ArrowPrimitiveType>::Native,
826 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
827 tz: Tz,
828 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
829 subtract_year_months::<Self>(timestamp, delta, tz)
830 }
831
832 pub fn subtract_day_time(
840 timestamp: <Self as ArrowPrimitiveType>::Native,
841 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
842 tz: Tz,
843 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
844 subtract_day_time::<Self>(timestamp, delta, tz)
845 }
846
847 pub fn subtract_month_day_nano(
855 timestamp: <Self as ArrowPrimitiveType>::Native,
856 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
857 tz: Tz,
858 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
859 subtract_month_day_nano::<Self>(timestamp, delta, tz)
860 }
861}
862
863impl IntervalYearMonthType {
864 #[inline]
871 pub fn make_value(
872 years: i32,
873 months: i32,
874 ) -> <IntervalYearMonthType as ArrowPrimitiveType>::Native {
875 years * 12 + months
876 }
877
878 #[inline]
886 pub fn to_months(i: <IntervalYearMonthType as ArrowPrimitiveType>::Native) -> i32 {
887 i
888 }
889}
890
891impl IntervalDayTimeType {
892 #[inline]
899 pub fn make_value(days: i32, milliseconds: i32) -> IntervalDayTime {
900 IntervalDayTime { days, milliseconds }
901 }
902
903 #[inline]
909 pub fn to_parts(i: IntervalDayTime) -> (i32, i32) {
910 (i.days, i.milliseconds)
911 }
912}
913
914impl IntervalMonthDayNanoType {
915 #[inline]
923 pub fn make_value(months: i32, days: i32, nanoseconds: i64) -> IntervalMonthDayNano {
924 IntervalMonthDayNano {
925 months,
926 days,
927 nanoseconds,
928 }
929 }
930
931 #[inline]
937 pub fn to_parts(i: IntervalMonthDayNano) -> (i32, i32, i64) {
938 (i.months, i.days, i.nanoseconds)
939 }
940}
941
942impl Date32Type {
943 #[deprecated(since = "58.0.0", note = "Use to_naive_date_opt instead.")]
949 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
950 Self::to_naive_date_opt(i)
951 .unwrap_or_else(|| panic!("Date32Type::to_naive_date overflowed for date: {i}",))
952 }
953
954 pub fn to_naive_date_opt(i: <Date32Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
962 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
963 Duration::try_days(i as i64).and_then(|d| epoch.checked_add_signed(d))
964 }
965
966 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
972 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
973 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
974 }
975
976 #[deprecated(
983 since = "58.0.0",
984 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
985 )]
986 pub fn add_year_months(
987 date: <Date32Type as ArrowPrimitiveType>::Native,
988 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
989 ) -> <Date32Type as ArrowPrimitiveType>::Native {
990 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
991 panic!("Date32Type::add_year_months overflowed for date: {date}, delta: {delta}",)
992 })
993 }
994
995 pub fn add_year_months_opt(
1004 date: <Date32Type as ArrowPrimitiveType>::Native,
1005 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1006 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1007 let prior = Date32Type::to_naive_date_opt(date)?;
1008 let months = IntervalYearMonthType::to_months(delta);
1009 let posterior = add_months_date(prior, months)?;
1010 Some(Date32Type::from_naive_date(posterior))
1011 }
1012
1013 #[deprecated(
1020 since = "58.0.0",
1021 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1022 )]
1023 pub fn add_day_time(
1024 date: <Date32Type as ArrowPrimitiveType>::Native,
1025 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1026 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1027 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1028 panic!("Date32Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
1029 })
1030 }
1031
1032 pub fn add_day_time_opt(
1041 date: <Date32Type as ArrowPrimitiveType>::Native,
1042 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1043 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1044 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1045 let res = Date32Type::to_naive_date_opt(date)?;
1046 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1047 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1048 Some(Date32Type::from_naive_date(res))
1049 }
1050
1051 #[deprecated(
1058 since = "58.0.0",
1059 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1060 )]
1061 pub fn add_month_day_nano(
1062 date: <Date32Type as ArrowPrimitiveType>::Native,
1063 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1064 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1065 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1066 panic!("Date32Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1067 })
1068 }
1069
1070 pub fn add_month_day_nano_opt(
1079 date: <Date32Type as ArrowPrimitiveType>::Native,
1080 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1081 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1082 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1083 let res = Date32Type::to_naive_date_opt(date)?;
1084 let res = add_months_date(res, months)?;
1085 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1086 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1087 Some(Date32Type::from_naive_date(res))
1088 }
1089
1090 #[deprecated(
1097 since = "58.0.0",
1098 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1099 )]
1100 pub fn subtract_year_months(
1101 date: <Date32Type as ArrowPrimitiveType>::Native,
1102 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1103 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1104 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1105 panic!("Date32Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1106 })
1107 }
1108
1109 pub fn subtract_year_months_opt(
1118 date: <Date32Type as ArrowPrimitiveType>::Native,
1119 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1120 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1121 let prior = Date32Type::to_naive_date_opt(date)?;
1122 let months = IntervalYearMonthType::to_months(-delta);
1123 let posterior = add_months_date(prior, months)?;
1124 Some(Date32Type::from_naive_date(posterior))
1125 }
1126
1127 #[deprecated(
1134 since = "58.0.0",
1135 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1136 )]
1137 pub fn subtract_day_time(
1138 date: <Date32Type as ArrowPrimitiveType>::Native,
1139 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1140 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1141 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1142 panic!("Date32Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1143 })
1144 }
1145
1146 pub fn subtract_day_time_opt(
1155 date: <Date32Type as ArrowPrimitiveType>::Native,
1156 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1157 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1158 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1159 let res = Date32Type::to_naive_date_opt(date)?;
1160 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1161 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1162 Some(Date32Type::from_naive_date(res))
1163 }
1164
1165 #[deprecated(
1172 since = "58.0.0",
1173 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1174 )]
1175 pub fn subtract_month_day_nano(
1176 date: <Date32Type as ArrowPrimitiveType>::Native,
1177 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1178 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1179 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1180 panic!(
1181 "Date32Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1182 )
1183 })
1184 }
1185
1186 pub fn subtract_month_day_nano_opt(
1195 date: <Date32Type as ArrowPrimitiveType>::Native,
1196 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1197 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1198 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1199 let res = Date32Type::to_naive_date_opt(date)?;
1200 let res = add_months_date(res, -months)?;
1201 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1202 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1203 Some(Date32Type::from_naive_date(res))
1204 }
1205}
1206
1207impl Date64Type {
1208 #[deprecated(since = "56.0.0", note = "Use to_naive_date_opt instead.")]
1214 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1215 Self::to_naive_date_opt(i)
1216 .unwrap_or_else(|| panic!("Date64Type::to_naive_date overflowed for date: {i}",))
1217 }
1218
1219 pub fn to_naive_date_opt(i: <Date64Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
1230 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1231 Duration::try_milliseconds(i).and_then(|d| epoch.checked_add_signed(d))
1232 }
1233
1234 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1240 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1241 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1242 }
1243
1244 #[deprecated(
1251 since = "56.0.0",
1252 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
1253 )]
1254 pub fn add_year_months(
1255 date: <Date64Type as ArrowPrimitiveType>::Native,
1256 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1257 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1258 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
1259 panic!("Date64Type::add_year_months overflowed for date: {date}, delta: {delta}",)
1260 })
1261 }
1262
1263 pub fn add_year_months_opt(
1272 date: <Date64Type as ArrowPrimitiveType>::Native,
1273 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1274 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1275 let prior = Date64Type::to_naive_date_opt(date)?;
1276 let months = IntervalYearMonthType::to_months(delta);
1277 let posterior = add_months_date(prior, months)?;
1278 Some(Date64Type::from_naive_date(posterior))
1279 }
1280
1281 #[deprecated(
1288 since = "56.0.0",
1289 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1290 )]
1291 pub fn add_day_time(
1292 date: <Date64Type as ArrowPrimitiveType>::Native,
1293 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1294 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1295 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1296 panic!("Date64Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
1297 })
1298 }
1299
1300 pub fn add_day_time_opt(
1309 date: <Date64Type as ArrowPrimitiveType>::Native,
1310 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1311 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1312 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1313 let res = Date64Type::to_naive_date_opt(date)?;
1314 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1315 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1316 Some(Date64Type::from_naive_date(res))
1317 }
1318
1319 #[deprecated(
1326 since = "56.0.0",
1327 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1328 )]
1329 pub fn add_month_day_nano(
1330 date: <Date64Type as ArrowPrimitiveType>::Native,
1331 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1332 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1333 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1334 panic!("Date64Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1335 })
1336 }
1337
1338 pub fn add_month_day_nano_opt(
1347 date: <Date64Type as ArrowPrimitiveType>::Native,
1348 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1349 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1350 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1351 let res = Date64Type::to_naive_date_opt(date)?;
1352 let res = add_months_date(res, months)?;
1353 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1354 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1355 Some(Date64Type::from_naive_date(res))
1356 }
1357
1358 #[deprecated(
1365 since = "56.0.0",
1366 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1367 )]
1368 pub fn subtract_year_months(
1369 date: <Date64Type as ArrowPrimitiveType>::Native,
1370 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1371 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1372 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1373 panic!("Date64Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1374 })
1375 }
1376
1377 pub fn subtract_year_months_opt(
1386 date: <Date64Type as ArrowPrimitiveType>::Native,
1387 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1388 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1389 let prior = Date64Type::to_naive_date_opt(date)?;
1390 let months = IntervalYearMonthType::to_months(-delta);
1391 let posterior = add_months_date(prior, months)?;
1392 Some(Date64Type::from_naive_date(posterior))
1393 }
1394
1395 #[deprecated(
1402 since = "56.0.0",
1403 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1404 )]
1405 pub fn subtract_day_time(
1406 date: <Date64Type as ArrowPrimitiveType>::Native,
1407 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1408 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1409 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1410 panic!("Date64Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1411 })
1412 }
1413
1414 pub fn subtract_day_time_opt(
1423 date: <Date64Type as ArrowPrimitiveType>::Native,
1424 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1425 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1426 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1427 let res = Date64Type::to_naive_date_opt(date)?;
1428 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1429 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1430 Some(Date64Type::from_naive_date(res))
1431 }
1432
1433 #[deprecated(
1440 since = "56.0.0",
1441 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1442 )]
1443 pub fn subtract_month_day_nano(
1444 date: <Date64Type as ArrowPrimitiveType>::Native,
1445 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1446 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1447 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1448 panic!(
1449 "Date64Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1450 )
1451 })
1452 }
1453
1454 pub fn subtract_month_day_nano_opt(
1463 date: <Date64Type as ArrowPrimitiveType>::Native,
1464 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1465 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1466 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1467 let res = Date64Type::to_naive_date_opt(date)?;
1468 let res = add_months_date(res, -months)?;
1469 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1470 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1471 Some(Date64Type::from_naive_date(res))
1472 }
1473}
1474
1475mod decimal {
1479 use super::*;
1480
1481 pub trait DecimalTypeSealed {}
1482 impl DecimalTypeSealed for Decimal32Type {}
1483 impl DecimalTypeSealed for Decimal64Type {}
1484 impl DecimalTypeSealed for Decimal128Type {}
1485 impl DecimalTypeSealed for Decimal256Type {}
1486}
1487
1488pub trait DecimalType:
1500 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1501{
1502 const BYTE_LENGTH: usize;
1504 const MAX_PRECISION: u8;
1506 const MAX_SCALE: i8;
1508 const MAX_FOR_EACH_PRECISION: &'static [Self::Native];
1510 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1512 const DEFAULT_TYPE: DataType;
1514
1515 const PREFIX: &'static str;
1517
1518 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1520
1521 fn validate_decimal_precision(
1523 value: Self::Native,
1524 precision: u8,
1525 scale: i8,
1526 ) -> Result<(), ArrowError>;
1527
1528 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1530}
1531
1532pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1540 precision: u8,
1541 scale: i8,
1542) -> Result<(), ArrowError> {
1543 if precision == 0 {
1544 return Err(ArrowError::InvalidArgumentError(format!(
1545 "precision cannot be 0, has to be between [1, {}]",
1546 T::MAX_PRECISION
1547 )));
1548 }
1549 if precision > T::MAX_PRECISION {
1550 return Err(ArrowError::InvalidArgumentError(format!(
1551 "precision {} is greater than max {}",
1552 precision,
1553 T::MAX_PRECISION
1554 )));
1555 }
1556 if scale > T::MAX_SCALE {
1557 return Err(ArrowError::InvalidArgumentError(format!(
1558 "scale {} is greater than max {}",
1559 scale,
1560 T::MAX_SCALE
1561 )));
1562 }
1563 if scale > 0 && scale as u8 > precision {
1564 return Err(ArrowError::InvalidArgumentError(format!(
1565 "scale {scale} is greater than precision {precision}"
1566 )));
1567 }
1568
1569 Ok(())
1570}
1571
1572#[derive(Debug)]
1574pub struct Decimal32Type {}
1575
1576impl DecimalType for Decimal32Type {
1577 const BYTE_LENGTH: usize = 4;
1578 const MAX_PRECISION: u8 = DECIMAL32_MAX_PRECISION;
1579 const MAX_SCALE: i8 = DECIMAL32_MAX_SCALE;
1580 const MAX_FOR_EACH_PRECISION: &'static [i32] =
1581 &arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
1582 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1583 const DEFAULT_TYPE: DataType =
1584 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1585 const PREFIX: &'static str = "Decimal32";
1586
1587 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1588 format_decimal_str(&value.to_string(), precision as usize, scale)
1589 }
1590
1591 fn validate_decimal_precision(num: i32, precision: u8, scale: i8) -> Result<(), ArrowError> {
1592 validate_decimal32_precision(num, precision, scale)
1593 }
1594
1595 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1596 is_validate_decimal32_precision(value, precision)
1597 }
1598}
1599
1600impl ArrowPrimitiveType for Decimal32Type {
1601 type Native = i32;
1602
1603 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1604}
1605
1606impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1607
1608#[derive(Debug)]
1610pub struct Decimal64Type {}
1611
1612impl DecimalType for Decimal64Type {
1613 const BYTE_LENGTH: usize = 8;
1614 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1615 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1616 const MAX_FOR_EACH_PRECISION: &'static [i64] =
1617 &arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
1618 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1619 const DEFAULT_TYPE: DataType =
1620 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1621 const PREFIX: &'static str = "Decimal64";
1622
1623 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1624 format_decimal_str(&value.to_string(), precision as usize, scale)
1625 }
1626
1627 fn validate_decimal_precision(num: i64, precision: u8, scale: i8) -> Result<(), ArrowError> {
1628 validate_decimal64_precision(num, precision, scale)
1629 }
1630
1631 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1632 is_validate_decimal64_precision(value, precision)
1633 }
1634}
1635
1636impl ArrowPrimitiveType for Decimal64Type {
1637 type Native = i64;
1638
1639 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1640}
1641
1642impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1643
1644#[derive(Debug)]
1646pub struct Decimal128Type {}
1647
1648impl DecimalType for Decimal128Type {
1649 const BYTE_LENGTH: usize = 16;
1650 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1651 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1652 const MAX_FOR_EACH_PRECISION: &'static [i128] =
1653 &arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
1654 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1655 const DEFAULT_TYPE: DataType =
1656 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1657 const PREFIX: &'static str = "Decimal128";
1658
1659 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1660 format_decimal_str(&value.to_string(), precision as usize, scale)
1661 }
1662
1663 fn validate_decimal_precision(num: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1664 validate_decimal_precision(num, precision, scale)
1665 }
1666
1667 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1668 is_validate_decimal_precision(value, precision)
1669 }
1670}
1671
1672impl ArrowPrimitiveType for Decimal128Type {
1673 type Native = i128;
1674
1675 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1676}
1677
1678impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1679
1680#[derive(Debug)]
1682pub struct Decimal256Type {}
1683
1684impl DecimalType for Decimal256Type {
1685 const BYTE_LENGTH: usize = 32;
1686 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1687 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1688 const MAX_FOR_EACH_PRECISION: &'static [i256] =
1689 &arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
1690 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1691 const DEFAULT_TYPE: DataType =
1692 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1693 const PREFIX: &'static str = "Decimal256";
1694
1695 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1696 format_decimal_str(&value.to_string(), precision as usize, scale)
1697 }
1698
1699 fn validate_decimal_precision(num: i256, precision: u8, scale: i8) -> Result<(), ArrowError> {
1700 validate_decimal256_precision(num, precision, scale)
1701 }
1702
1703 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1704 is_validate_decimal256_precision(value, precision)
1705 }
1706}
1707
1708impl ArrowPrimitiveType for Decimal256Type {
1709 type Native = i256;
1710
1711 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1712}
1713
1714impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1715
1716pub(crate) mod bytes {
1720 use super::*;
1721
1722 pub trait ByteArrayTypeSealed {}
1723 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1724 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1725
1726 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1727 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1728
1729 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1733 }
1734
1735 impl ByteArrayNativeType for [u8] {
1736 #[inline]
1737 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1738 Some(b)
1739 }
1740
1741 #[inline]
1742 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1743 b
1744 }
1745 }
1746
1747 impl ByteArrayNativeType for str {
1748 #[inline]
1749 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1750 std::str::from_utf8(b).ok()
1751 }
1752
1753 #[inline]
1754 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1755 unsafe { std::str::from_utf8_unchecked(b) }
1756 }
1757 }
1758}
1759
1760pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1764 type Offset: OffsetSizeTrait;
1766 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1770
1771 const PREFIX: &'static str;
1773
1774 const DATA_TYPE: DataType;
1776
1777 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1779}
1780
1781pub struct GenericStringType<O: OffsetSizeTrait> {
1783 phantom: PhantomData<O>,
1784}
1785
1786impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1787 type Offset = O;
1788 type Native = str;
1789 const PREFIX: &'static str = "String";
1790
1791 const DATA_TYPE: DataType = if O::IS_LARGE {
1792 DataType::LargeUtf8
1793 } else {
1794 DataType::Utf8
1795 };
1796
1797 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1798 let validated = std::str::from_utf8(values).map_err(|e| {
1800 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1801 })?;
1802
1803 for offset in offsets.iter() {
1805 let o = offset.as_usize();
1806 if !validated.is_char_boundary(o) {
1807 if o < validated.len() {
1808 return Err(ArrowError::InvalidArgumentError(format!(
1809 "Split UTF-8 codepoint at offset {o}"
1810 )));
1811 }
1812 return Err(ArrowError::InvalidArgumentError(format!(
1813 "Offset of {o} exceeds length of values {}",
1814 validated.len()
1815 )));
1816 }
1817 }
1818 Ok(())
1819 }
1820}
1821
1822pub type Utf8Type = GenericStringType<i32>;
1824pub type LargeUtf8Type = GenericStringType<i64>;
1826
1827pub struct GenericBinaryType<O: OffsetSizeTrait> {
1829 phantom: PhantomData<O>,
1830}
1831
1832impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1833 type Offset = O;
1834 type Native = [u8];
1835 const PREFIX: &'static str = "Binary";
1836
1837 const DATA_TYPE: DataType = if O::IS_LARGE {
1838 DataType::LargeBinary
1839 } else {
1840 DataType::Binary
1841 };
1842
1843 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1844 let max_offset = offsets.last().unwrap().as_usize();
1846 if values.len() < max_offset {
1847 return Err(ArrowError::InvalidArgumentError(format!(
1848 "Maximum offset of {max_offset} is larger than values of length {}",
1849 values.len()
1850 )));
1851 }
1852 Ok(())
1853 }
1854}
1855
1856pub type BinaryType = GenericBinaryType<i32>;
1858pub type LargeBinaryType = GenericBinaryType<i64>;
1860
1861mod byte_view {
1862 use crate::types::{BinaryViewType, StringViewType};
1863
1864 pub trait Sealed: Send + Sync {}
1865 impl Sealed for StringViewType {}
1866 impl Sealed for BinaryViewType {}
1867}
1868
1869pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1871 const IS_UTF8: bool;
1873
1874 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1876 DataType::Utf8View
1877 } else {
1878 DataType::BinaryView
1879 };
1880
1881 const PREFIX: &'static str;
1883
1884 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1888
1889 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1891
1892 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1894}
1895
1896#[derive(PartialEq)]
1898pub struct StringViewType {}
1899
1900impl ByteViewType for StringViewType {
1901 const IS_UTF8: bool = true;
1902 const PREFIX: &'static str = "String";
1903
1904 type Native = str;
1905 type Owned = String;
1906
1907 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1908 validate_string_view(views, buffers)
1909 }
1910}
1911
1912#[derive(PartialEq)]
1914pub struct BinaryViewType {}
1915
1916impl ByteViewType for BinaryViewType {
1917 const IS_UTF8: bool = false;
1918 const PREFIX: &'static str = "Binary";
1919 type Native = [u8];
1920 type Owned = Vec<u8>;
1921
1922 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1923 validate_binary_view(views, buffers)
1924 }
1925}
1926
1927#[cfg(test)]
1928mod tests {
1929 use super::*;
1930 use arrow_data::{BufferSpec, layout};
1931 use chrono::DateTime;
1932
1933 #[test]
1934 fn month_day_nano_should_roundtrip() {
1935 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1936 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1937 }
1938
1939 #[test]
1940 fn month_day_nano_should_roundtrip_neg() {
1941 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1942 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1943 }
1944
1945 #[test]
1946 fn day_time_should_roundtrip() {
1947 let value = IntervalDayTimeType::make_value(1, 2);
1948 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1949 }
1950
1951 #[test]
1952 fn day_time_should_roundtrip_neg() {
1953 let value = IntervalDayTimeType::make_value(-1, -2);
1954 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1955 }
1956
1957 #[test]
1958 fn year_month_should_roundtrip() {
1959 let value = IntervalYearMonthType::make_value(1, 2);
1960 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1961 }
1962
1963 #[test]
1964 fn year_month_should_roundtrip_neg() {
1965 let value = IntervalYearMonthType::make_value(-1, -2);
1966 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1967 }
1968
1969 fn test_layout<T: ArrowPrimitiveType>() {
1970 let layout = layout(&T::DATA_TYPE);
1971
1972 assert_eq!(layout.buffers.len(), 1);
1973
1974 let spec = &layout.buffers[0];
1975 assert_eq!(
1976 spec,
1977 &BufferSpec::FixedWidth {
1978 byte_width: std::mem::size_of::<T::Native>(),
1979 alignment: std::mem::align_of::<T::Native>(),
1980 }
1981 );
1982 }
1983
1984 #[test]
1985 fn test_layouts() {
1986 test_layout::<Int8Type>();
1987 test_layout::<Int16Type>();
1988 test_layout::<Int32Type>();
1989 test_layout::<Int64Type>();
1990 test_layout::<UInt8Type>();
1991 test_layout::<UInt16Type>();
1992 test_layout::<UInt32Type>();
1993 test_layout::<UInt64Type>();
1994 test_layout::<Float16Type>();
1995 test_layout::<Float32Type>();
1996 test_layout::<Float64Type>();
1997 test_layout::<Decimal32Type>();
1998 test_layout::<Decimal64Type>();
1999 test_layout::<Decimal128Type>();
2000 test_layout::<Decimal256Type>();
2001 test_layout::<TimestampNanosecondType>();
2002 test_layout::<TimestampMillisecondType>();
2003 test_layout::<TimestampMicrosecondType>();
2004 test_layout::<TimestampNanosecondType>();
2005 test_layout::<TimestampSecondType>();
2006 test_layout::<Date32Type>();
2007 test_layout::<Date64Type>();
2008 test_layout::<Time32SecondType>();
2009 test_layout::<Time32MillisecondType>();
2010 test_layout::<Time64MicrosecondType>();
2011 test_layout::<Time64NanosecondType>();
2012 test_layout::<IntervalMonthDayNanoType>();
2013 test_layout::<IntervalDayTimeType>();
2014 test_layout::<IntervalYearMonthType>();
2015 test_layout::<DurationNanosecondType>();
2016 test_layout::<DurationMicrosecondType>();
2017 test_layout::<DurationMillisecondType>();
2018 test_layout::<DurationSecondType>();
2019 }
2020
2021 #[test]
2022 fn timestamp_from_datetime() {
2023 use chrono::{FixedOffset, NaiveDate, NaiveTime, Utc};
2024
2025 let date = NaiveDate::from_ymd_opt(2021, 1, 1).unwrap();
2027 let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
2028 let naive = NaiveDateTime::new(date, time);
2029 let datetime_utc = Utc.from_utc_datetime(&naive);
2030
2031 assert_eq!(
2032 TimestampSecondType::from_datetime(datetime_utc).unwrap(),
2033 1609502400
2034 );
2035 assert_eq!(
2036 TimestampMillisecondType::from_datetime(datetime_utc).unwrap(),
2037 1609502400000
2038 );
2039 assert_eq!(
2040 TimestampMicrosecondType::from_datetime(datetime_utc).unwrap(),
2041 1609502400000000
2042 );
2043 assert_eq!(
2044 TimestampNanosecondType::from_datetime(datetime_utc).unwrap(),
2045 1609502400000000000
2046 );
2047
2048 let tz_plus_8 = FixedOffset::east_opt(8 * 3600).unwrap();
2050 let datetime_plus_8 = tz_plus_8.from_local_datetime(&naive).unwrap();
2051 assert_eq!(
2052 TimestampSecondType::from_datetime(datetime_plus_8).unwrap(),
2053 1609502400 - 28800
2054 );
2055
2056 let datetime = DateTime::from_timestamp(1000000000, 123456789).unwrap();
2058 assert_eq!(
2059 TimestampSecondType::from_datetime(datetime).unwrap(),
2060 1000000000
2061 );
2062 assert_eq!(
2063 TimestampMillisecondType::from_datetime(datetime).unwrap(),
2064 1000000000123
2065 );
2066 assert_eq!(
2067 TimestampMicrosecondType::from_datetime(datetime).unwrap(),
2068 1000000000123456
2069 );
2070 assert_eq!(
2071 TimestampNanosecondType::from_datetime(datetime).unwrap(),
2072 1000000000123456789
2073 );
2074 }
2075
2076 #[test]
2077 fn timestamp_from_datetime_overflow() {
2078 let far_past = DateTime::from_timestamp(-10_000_000_000, 0).unwrap();
2080 assert!(TimestampNanosecondType::from_datetime(far_past).is_none());
2081 assert!(TimestampSecondType::from_datetime(far_past).is_some());
2083 assert!(TimestampMillisecondType::from_datetime(far_past).is_some());
2084 assert!(TimestampMicrosecondType::from_datetime(far_past).is_some());
2085
2086 let far_future = DateTime::from_timestamp(10_000_000_000, 0).unwrap();
2087 assert!(TimestampNanosecondType::from_datetime(far_future).is_none());
2088 assert!(TimestampSecondType::from_datetime(far_future).is_some());
2089 assert!(TimestampMillisecondType::from_datetime(far_future).is_some());
2090 assert!(TimestampMicrosecondType::from_datetime(far_future).is_some());
2091 }
2092
2093 #[test]
2094 fn timestamp_from_naive_datetime() {
2095 use crate::temporal_conversions::as_datetime_with_timezone;
2096 use chrono::{NaiveDate, NaiveTime};
2097
2098 let date = NaiveDate::from_ymd_opt(2021, 1, 1).unwrap();
2099 let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
2100 let naive = NaiveDateTime::new(date, time);
2101
2102 assert_eq!(
2104 TimestampSecondType::from_naive_datetime(naive, None).unwrap(),
2105 1609502400
2106 );
2107 assert_eq!(
2108 TimestampMillisecondType::from_naive_datetime(naive, None).unwrap(),
2109 1609502400000
2110 );
2111
2112 let tz: Tz = "-05:00".parse().unwrap();
2114 let ts_sec = TimestampSecondType::from_naive_datetime(naive, Some(&tz)).unwrap();
2115 assert_eq!(ts_sec, 1609502400 + 5 * 3600);
2116
2117 let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();
2119 let time = NaiveTime::from_hms_opt(14, 30, 45).unwrap();
2120 let naive = NaiveDateTime::new(date, time);
2121 let tz: Tz = "+01:00".parse().unwrap();
2122
2123 let ts_usec = TimestampMicrosecondType::from_naive_datetime(naive, Some(&tz)).unwrap();
2124 let recovered = as_datetime_with_timezone::<TimestampMicrosecondType>(ts_usec, tz).unwrap();
2125 assert_eq!(recovered.naive_local(), naive);
2126 }
2127
2128 #[test]
2129 #[cfg(feature = "chrono-tz")]
2130 fn timestamp_from_naive_datetime_ambiguous() {
2131 use chrono::{NaiveDate, NaiveTime};
2132
2133 let date = NaiveDate::from_ymd_opt(2024, 11, 3).unwrap();
2136 let time = NaiveTime::from_hms_opt(1, 30, 0).unwrap();
2137 let naive = NaiveDateTime::new(date, time);
2138 let tz: Tz = "America/New_York".parse().unwrap();
2139
2140 let result = TimestampSecondType::from_naive_datetime(naive, Some(&tz));
2142 assert!(result.is_some());
2143 assert_eq!(result.unwrap(), 1730611800);
2144 }
2145
2146 #[test]
2147 #[cfg(feature = "chrono-tz")]
2148 fn timestamp_from_naive_datetime_none() {
2149 use chrono::{NaiveDate, NaiveTime};
2150
2151 let date = NaiveDate::from_ymd_opt(2024, 3, 10).unwrap();
2154 let time = NaiveTime::from_hms_opt(2, 30, 0).unwrap();
2155 let naive = NaiveDateTime::new(date, time);
2156 let tz: Tz = "America/New_York".parse().unwrap();
2157
2158 let result = TimestampSecondType::from_naive_datetime(naive, Some(&tz));
2160 assert!(result.is_none());
2161
2162 assert!(TimestampMillisecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2164 assert!(TimestampMicrosecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2165 assert!(TimestampNanosecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2166 }
2167}