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 fn make_value(naive: NaiveDateTime) -> Option<i64>;
328
329 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64>;
338
339 fn from_naive_datetime(naive: NaiveDateTime, tz: Option<&Tz>) -> Option<i64> {
347 match tz {
348 Some(tz) => match tz.from_local_datetime(&naive) {
349 chrono::offset::LocalResult::Single(dt) => Self::from_datetime(dt),
350 chrono::offset::LocalResult::Ambiguous(dt1, _) => Self::from_datetime(dt1),
351 chrono::offset::LocalResult::None => None,
352 },
353 None => Self::make_value(naive),
354 }
355 }
356}
357
358impl ArrowTimestampType for TimestampSecondType {
359 const UNIT: TimeUnit = TimeUnit::Second;
360
361 fn make_value(naive: NaiveDateTime) -> Option<i64> {
362 Some(naive.and_utc().timestamp())
363 }
364
365 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
366 Some(datetime.timestamp())
367 }
368}
369impl ArrowTimestampType for TimestampMillisecondType {
370 const UNIT: TimeUnit = TimeUnit::Millisecond;
371
372 fn make_value(naive: NaiveDateTime) -> Option<i64> {
373 let utc = naive.and_utc();
374 let millis = utc.timestamp().checked_mul(1_000)?;
375 millis.checked_add(utc.timestamp_subsec_millis() as i64)
376 }
377
378 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
379 let millis = datetime.timestamp().checked_mul(1_000)?;
380 millis.checked_add(datetime.timestamp_subsec_millis() as i64)
381 }
382}
383impl ArrowTimestampType for TimestampMicrosecondType {
384 const UNIT: TimeUnit = TimeUnit::Microsecond;
385
386 fn make_value(naive: NaiveDateTime) -> Option<i64> {
387 let utc = naive.and_utc();
388 let micros = utc.timestamp().checked_mul(1_000_000)?;
389 micros.checked_add(utc.timestamp_subsec_micros() as i64)
390 }
391
392 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
393 let micros = datetime.timestamp().checked_mul(1_000_000)?;
394 micros.checked_add(datetime.timestamp_subsec_micros() as i64)
395 }
396}
397impl ArrowTimestampType for TimestampNanosecondType {
398 const UNIT: TimeUnit = TimeUnit::Nanosecond;
399
400 fn make_value(naive: NaiveDateTime) -> Option<i64> {
401 let utc = naive.and_utc();
402 let nanos = utc.timestamp().checked_mul(1_000_000_000)?;
403 nanos.checked_add(utc.timestamp_subsec_nanos() as i64)
404 }
405
406 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
407 datetime.timestamp_nanos_opt()
408 }
409}
410
411fn add_year_months<T: ArrowTimestampType>(
412 timestamp: <T as ArrowPrimitiveType>::Native,
413 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
414 tz: Tz,
415) -> Option<<T as ArrowPrimitiveType>::Native> {
416 let months = IntervalYearMonthType::to_months(delta);
417 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
418 let res = add_months_datetime(res, months)?;
419 let res = res.naive_utc();
420 T::make_value(res)
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 let res = res.naive_utc();
433 T::make_value(res)
434}
435
436fn add_month_day_nano<T: ArrowTimestampType>(
437 timestamp: <T as ArrowPrimitiveType>::Native,
438 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
439 tz: Tz,
440) -> Option<<T as ArrowPrimitiveType>::Native> {
441 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
442 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
443 let res = add_months_datetime(res, months)?;
444 let res = add_days_datetime(res, days)?;
445 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
446 let res = res.naive_utc();
447 T::make_value(res)
448}
449
450fn subtract_year_months<T: ArrowTimestampType>(
451 timestamp: <T as ArrowPrimitiveType>::Native,
452 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
453 tz: Tz,
454) -> Option<<T as ArrowPrimitiveType>::Native> {
455 let months = IntervalYearMonthType::to_months(delta);
456 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
457 let res = sub_months_datetime(res, months)?;
458 let res = res.naive_utc();
459 T::make_value(res)
460}
461
462fn subtract_day_time<T: ArrowTimestampType>(
463 timestamp: <T as ArrowPrimitiveType>::Native,
464 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
465 tz: Tz,
466) -> Option<<T as ArrowPrimitiveType>::Native> {
467 let (days, ms) = IntervalDayTimeType::to_parts(delta);
468 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
469 let res = sub_days_datetime(res, days)?;
470 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
471 let res = res.naive_utc();
472 T::make_value(res)
473}
474
475fn subtract_month_day_nano<T: ArrowTimestampType>(
476 timestamp: <T as ArrowPrimitiveType>::Native,
477 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
478 tz: Tz,
479) -> Option<<T as ArrowPrimitiveType>::Native> {
480 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
481 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
482 let res = sub_months_datetime(res, months)?;
483 let res = sub_days_datetime(res, days)?;
484 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
485 let res = res.naive_utc();
486 T::make_value(res)
487}
488
489impl TimestampSecondType {
490 pub fn add_year_months(
500 timestamp: <Self as ArrowPrimitiveType>::Native,
501 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
502 tz: Tz,
503 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
504 add_year_months::<Self>(timestamp, delta, tz)
505 }
506
507 pub fn add_day_time(
517 timestamp: <Self as ArrowPrimitiveType>::Native,
518 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
519 tz: Tz,
520 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
521 add_day_time::<Self>(timestamp, delta, tz)
522 }
523
524 pub fn add_month_day_nano(
533 timestamp: <Self as ArrowPrimitiveType>::Native,
534 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
535 tz: Tz,
536 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
537 add_month_day_nano::<Self>(timestamp, delta, tz)
538 }
539
540 pub fn subtract_year_months(
550 timestamp: <Self as ArrowPrimitiveType>::Native,
551 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
552 tz: Tz,
553 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
554 subtract_year_months::<Self>(timestamp, delta, tz)
555 }
556
557 pub fn subtract_day_time(
567 timestamp: <Self as ArrowPrimitiveType>::Native,
568 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
569 tz: Tz,
570 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
571 subtract_day_time::<Self>(timestamp, delta, tz)
572 }
573
574 pub fn subtract_month_day_nano(
584 timestamp: <Self as ArrowPrimitiveType>::Native,
585 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
586 tz: Tz,
587 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
588 subtract_month_day_nano::<Self>(timestamp, delta, tz)
589 }
590}
591
592impl TimestampMicrosecondType {
593 pub fn add_year_months(
601 timestamp: <Self as ArrowPrimitiveType>::Native,
602 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
603 tz: Tz,
604 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
605 add_year_months::<Self>(timestamp, delta, tz)
606 }
607
608 pub fn add_day_time(
616 timestamp: <Self as ArrowPrimitiveType>::Native,
617 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
618 tz: Tz,
619 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
620 add_day_time::<Self>(timestamp, delta, tz)
621 }
622
623 pub fn add_month_day_nano(
631 timestamp: <Self as ArrowPrimitiveType>::Native,
632 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
633 tz: Tz,
634 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
635 add_month_day_nano::<Self>(timestamp, delta, tz)
636 }
637
638 pub fn subtract_year_months(
646 timestamp: <Self as ArrowPrimitiveType>::Native,
647 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
648 tz: Tz,
649 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
650 subtract_year_months::<Self>(timestamp, delta, tz)
651 }
652
653 pub fn subtract_day_time(
661 timestamp: <Self as ArrowPrimitiveType>::Native,
662 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
663 tz: Tz,
664 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
665 subtract_day_time::<Self>(timestamp, delta, tz)
666 }
667
668 pub fn subtract_month_day_nano(
676 timestamp: <Self as ArrowPrimitiveType>::Native,
677 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
678 tz: Tz,
679 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
680 subtract_month_day_nano::<Self>(timestamp, delta, tz)
681 }
682}
683
684impl TimestampMillisecondType {
685 pub fn add_year_months(
693 timestamp: <Self as ArrowPrimitiveType>::Native,
694 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
695 tz: Tz,
696 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
697 add_year_months::<Self>(timestamp, delta, tz)
698 }
699
700 pub fn add_day_time(
708 timestamp: <Self as ArrowPrimitiveType>::Native,
709 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
710 tz: Tz,
711 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
712 add_day_time::<Self>(timestamp, delta, tz)
713 }
714
715 pub fn add_month_day_nano(
723 timestamp: <Self as ArrowPrimitiveType>::Native,
724 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
725 tz: Tz,
726 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
727 add_month_day_nano::<Self>(timestamp, delta, tz)
728 }
729
730 pub fn subtract_year_months(
738 timestamp: <Self as ArrowPrimitiveType>::Native,
739 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
740 tz: Tz,
741 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
742 subtract_year_months::<Self>(timestamp, delta, tz)
743 }
744
745 pub fn subtract_day_time(
753 timestamp: <Self as ArrowPrimitiveType>::Native,
754 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
755 tz: Tz,
756 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
757 subtract_day_time::<Self>(timestamp, delta, tz)
758 }
759
760 pub fn subtract_month_day_nano(
768 timestamp: <Self as ArrowPrimitiveType>::Native,
769 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
770 tz: Tz,
771 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
772 subtract_month_day_nano::<Self>(timestamp, delta, tz)
773 }
774}
775
776impl TimestampNanosecondType {
777 pub fn add_year_months(
785 timestamp: <Self as ArrowPrimitiveType>::Native,
786 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
787 tz: Tz,
788 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
789 add_year_months::<Self>(timestamp, delta, tz)
790 }
791
792 pub fn add_day_time(
800 timestamp: <Self as ArrowPrimitiveType>::Native,
801 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
802 tz: Tz,
803 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
804 add_day_time::<Self>(timestamp, delta, tz)
805 }
806
807 pub fn add_month_day_nano(
815 timestamp: <Self as ArrowPrimitiveType>::Native,
816 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
817 tz: Tz,
818 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
819 add_month_day_nano::<Self>(timestamp, delta, tz)
820 }
821
822 pub fn subtract_year_months(
830 timestamp: <Self as ArrowPrimitiveType>::Native,
831 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
832 tz: Tz,
833 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
834 subtract_year_months::<Self>(timestamp, delta, tz)
835 }
836
837 pub fn subtract_day_time(
845 timestamp: <Self as ArrowPrimitiveType>::Native,
846 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
847 tz: Tz,
848 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
849 subtract_day_time::<Self>(timestamp, delta, tz)
850 }
851
852 pub fn subtract_month_day_nano(
860 timestamp: <Self as ArrowPrimitiveType>::Native,
861 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
862 tz: Tz,
863 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
864 subtract_month_day_nano::<Self>(timestamp, delta, tz)
865 }
866}
867
868impl IntervalYearMonthType {
869 #[inline]
876 pub fn make_value(
877 years: i32,
878 months: i32,
879 ) -> <IntervalYearMonthType as ArrowPrimitiveType>::Native {
880 years * 12 + months
881 }
882
883 #[inline]
891 pub fn to_months(i: <IntervalYearMonthType as ArrowPrimitiveType>::Native) -> i32 {
892 i
893 }
894}
895
896impl IntervalDayTimeType {
897 #[inline]
904 pub fn make_value(days: i32, milliseconds: i32) -> IntervalDayTime {
905 IntervalDayTime { days, milliseconds }
906 }
907
908 #[inline]
914 pub fn to_parts(i: IntervalDayTime) -> (i32, i32) {
915 (i.days, i.milliseconds)
916 }
917}
918
919impl IntervalMonthDayNanoType {
920 #[inline]
928 pub fn make_value(months: i32, days: i32, nanoseconds: i64) -> IntervalMonthDayNano {
929 IntervalMonthDayNano {
930 months,
931 days,
932 nanoseconds,
933 }
934 }
935
936 #[inline]
942 pub fn to_parts(i: IntervalMonthDayNano) -> (i32, i32, i64) {
943 (i.months, i.days, i.nanoseconds)
944 }
945}
946
947impl Date32Type {
948 #[deprecated(since = "58.0.0", note = "Use to_naive_date_opt instead.")]
954 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
955 Self::to_naive_date_opt(i)
956 .unwrap_or_else(|| panic!("Date32Type::to_naive_date overflowed for date: {i}",))
957 }
958
959 pub fn to_naive_date_opt(i: <Date32Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
967 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
968 Duration::try_days(i as i64).and_then(|d| epoch.checked_add_signed(d))
969 }
970
971 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
977 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
978 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
979 }
980
981 #[deprecated(
988 since = "58.0.0",
989 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
990 )]
991 pub fn add_year_months(
992 date: <Date32Type as ArrowPrimitiveType>::Native,
993 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
994 ) -> <Date32Type as ArrowPrimitiveType>::Native {
995 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
996 panic!("Date32Type::add_year_months overflowed for date: {date}, delta: {delta}",)
997 })
998 }
999
1000 pub fn add_year_months_opt(
1009 date: <Date32Type as ArrowPrimitiveType>::Native,
1010 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1011 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1012 let prior = Date32Type::to_naive_date_opt(date)?;
1013 let months = IntervalYearMonthType::to_months(delta);
1014 let posterior = add_months_date(prior, months)?;
1015 Some(Date32Type::from_naive_date(posterior))
1016 }
1017
1018 #[deprecated(
1025 since = "58.0.0",
1026 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1027 )]
1028 pub fn add_day_time(
1029 date: <Date32Type as ArrowPrimitiveType>::Native,
1030 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1031 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1032 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1033 panic!("Date32Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
1034 })
1035 }
1036
1037 pub fn add_day_time_opt(
1046 date: <Date32Type as ArrowPrimitiveType>::Native,
1047 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1048 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1049 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1050 let res = Date32Type::to_naive_date_opt(date)?;
1051 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1052 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1053 Some(Date32Type::from_naive_date(res))
1054 }
1055
1056 #[deprecated(
1063 since = "58.0.0",
1064 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1065 )]
1066 pub fn add_month_day_nano(
1067 date: <Date32Type as ArrowPrimitiveType>::Native,
1068 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1069 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1070 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1071 panic!("Date32Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1072 })
1073 }
1074
1075 pub fn add_month_day_nano_opt(
1084 date: <Date32Type as ArrowPrimitiveType>::Native,
1085 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1086 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1087 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1088 let res = Date32Type::to_naive_date_opt(date)?;
1089 let res = add_months_date(res, months)?;
1090 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1091 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1092 Some(Date32Type::from_naive_date(res))
1093 }
1094
1095 #[deprecated(
1102 since = "58.0.0",
1103 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1104 )]
1105 pub fn subtract_year_months(
1106 date: <Date32Type as ArrowPrimitiveType>::Native,
1107 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1108 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1109 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1110 panic!("Date32Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1111 })
1112 }
1113
1114 pub fn subtract_year_months_opt(
1123 date: <Date32Type as ArrowPrimitiveType>::Native,
1124 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1125 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1126 let prior = Date32Type::to_naive_date_opt(date)?;
1127 let months = IntervalYearMonthType::to_months(-delta);
1128 let posterior = add_months_date(prior, months)?;
1129 Some(Date32Type::from_naive_date(posterior))
1130 }
1131
1132 #[deprecated(
1139 since = "58.0.0",
1140 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1141 )]
1142 pub fn subtract_day_time(
1143 date: <Date32Type as ArrowPrimitiveType>::Native,
1144 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1145 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1146 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1147 panic!("Date32Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1148 })
1149 }
1150
1151 pub fn subtract_day_time_opt(
1160 date: <Date32Type as ArrowPrimitiveType>::Native,
1161 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1162 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1163 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1164 let res = Date32Type::to_naive_date_opt(date)?;
1165 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1166 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1167 Some(Date32Type::from_naive_date(res))
1168 }
1169
1170 #[deprecated(
1177 since = "58.0.0",
1178 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1179 )]
1180 pub fn subtract_month_day_nano(
1181 date: <Date32Type as ArrowPrimitiveType>::Native,
1182 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1183 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1184 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1185 panic!(
1186 "Date32Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1187 )
1188 })
1189 }
1190
1191 pub fn subtract_month_day_nano_opt(
1200 date: <Date32Type as ArrowPrimitiveType>::Native,
1201 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1202 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1203 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1204 let res = Date32Type::to_naive_date_opt(date)?;
1205 let res = add_months_date(res, -months)?;
1206 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1207 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1208 Some(Date32Type::from_naive_date(res))
1209 }
1210}
1211
1212impl Date64Type {
1213 #[deprecated(since = "56.0.0", note = "Use to_naive_date_opt instead.")]
1219 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1220 Self::to_naive_date_opt(i)
1221 .unwrap_or_else(|| panic!("Date64Type::to_naive_date overflowed for date: {i}",))
1222 }
1223
1224 pub fn to_naive_date_opt(i: <Date64Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
1235 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1236 Duration::try_milliseconds(i).and_then(|d| epoch.checked_add_signed(d))
1237 }
1238
1239 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1245 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1246 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1247 }
1248
1249 #[deprecated(
1256 since = "56.0.0",
1257 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
1258 )]
1259 pub fn add_year_months(
1260 date: <Date64Type as ArrowPrimitiveType>::Native,
1261 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1262 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1263 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
1264 panic!("Date64Type::add_year_months overflowed for date: {date}, delta: {delta}",)
1265 })
1266 }
1267
1268 pub fn add_year_months_opt(
1277 date: <Date64Type as ArrowPrimitiveType>::Native,
1278 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1279 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1280 let prior = Date64Type::to_naive_date_opt(date)?;
1281 let months = IntervalYearMonthType::to_months(delta);
1282 let posterior = add_months_date(prior, months)?;
1283 Some(Date64Type::from_naive_date(posterior))
1284 }
1285
1286 #[deprecated(
1293 since = "56.0.0",
1294 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1295 )]
1296 pub fn add_day_time(
1297 date: <Date64Type as ArrowPrimitiveType>::Native,
1298 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1299 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1300 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1301 panic!("Date64Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
1302 })
1303 }
1304
1305 pub fn add_day_time_opt(
1314 date: <Date64Type as ArrowPrimitiveType>::Native,
1315 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1316 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1317 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1318 let res = Date64Type::to_naive_date_opt(date)?;
1319 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1320 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1321 Some(Date64Type::from_naive_date(res))
1322 }
1323
1324 #[deprecated(
1331 since = "56.0.0",
1332 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1333 )]
1334 pub fn add_month_day_nano(
1335 date: <Date64Type as ArrowPrimitiveType>::Native,
1336 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1337 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1338 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1339 panic!("Date64Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1340 })
1341 }
1342
1343 pub fn add_month_day_nano_opt(
1352 date: <Date64Type as ArrowPrimitiveType>::Native,
1353 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1354 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1355 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1356 let res = Date64Type::to_naive_date_opt(date)?;
1357 let res = add_months_date(res, months)?;
1358 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1359 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1360 Some(Date64Type::from_naive_date(res))
1361 }
1362
1363 #[deprecated(
1370 since = "56.0.0",
1371 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1372 )]
1373 pub fn subtract_year_months(
1374 date: <Date64Type as ArrowPrimitiveType>::Native,
1375 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1376 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1377 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1378 panic!("Date64Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1379 })
1380 }
1381
1382 pub fn subtract_year_months_opt(
1391 date: <Date64Type as ArrowPrimitiveType>::Native,
1392 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1393 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1394 let prior = Date64Type::to_naive_date_opt(date)?;
1395 let months = IntervalYearMonthType::to_months(-delta);
1396 let posterior = add_months_date(prior, months)?;
1397 Some(Date64Type::from_naive_date(posterior))
1398 }
1399
1400 #[deprecated(
1407 since = "56.0.0",
1408 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1409 )]
1410 pub fn subtract_day_time(
1411 date: <Date64Type as ArrowPrimitiveType>::Native,
1412 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1413 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1414 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1415 panic!("Date64Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1416 })
1417 }
1418
1419 pub fn subtract_day_time_opt(
1428 date: <Date64Type as ArrowPrimitiveType>::Native,
1429 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1430 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1431 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1432 let res = Date64Type::to_naive_date_opt(date)?;
1433 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1434 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1435 Some(Date64Type::from_naive_date(res))
1436 }
1437
1438 #[deprecated(
1445 since = "56.0.0",
1446 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1447 )]
1448 pub fn subtract_month_day_nano(
1449 date: <Date64Type as ArrowPrimitiveType>::Native,
1450 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1451 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1452 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1453 panic!(
1454 "Date64Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1455 )
1456 })
1457 }
1458
1459 pub fn subtract_month_day_nano_opt(
1468 date: <Date64Type as ArrowPrimitiveType>::Native,
1469 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1470 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1471 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1472 let res = Date64Type::to_naive_date_opt(date)?;
1473 let res = add_months_date(res, -months)?;
1474 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1475 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1476 Some(Date64Type::from_naive_date(res))
1477 }
1478}
1479
1480mod decimal {
1484 use super::*;
1485
1486 pub trait DecimalTypeSealed {}
1487 impl DecimalTypeSealed for Decimal32Type {}
1488 impl DecimalTypeSealed for Decimal64Type {}
1489 impl DecimalTypeSealed for Decimal128Type {}
1490 impl DecimalTypeSealed for Decimal256Type {}
1491}
1492
1493pub trait DecimalType:
1505 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1506{
1507 const BYTE_LENGTH: usize;
1509 const MAX_PRECISION: u8;
1511 const MAX_SCALE: i8;
1513 const MAX_FOR_EACH_PRECISION: &'static [Self::Native];
1515 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1517 const DEFAULT_TYPE: DataType;
1519
1520 const PREFIX: &'static str;
1522
1523 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1525
1526 fn validate_decimal_precision(
1528 value: Self::Native,
1529 precision: u8,
1530 scale: i8,
1531 ) -> Result<(), ArrowError>;
1532
1533 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1535}
1536
1537pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1545 precision: u8,
1546 scale: i8,
1547) -> Result<(), ArrowError> {
1548 if precision == 0 {
1549 return Err(ArrowError::InvalidArgumentError(format!(
1550 "precision cannot be 0, has to be between [1, {}]",
1551 T::MAX_PRECISION
1552 )));
1553 }
1554 if precision > T::MAX_PRECISION {
1555 return Err(ArrowError::InvalidArgumentError(format!(
1556 "precision {} is greater than max {}",
1557 precision,
1558 T::MAX_PRECISION
1559 )));
1560 }
1561 if scale > T::MAX_SCALE {
1562 return Err(ArrowError::InvalidArgumentError(format!(
1563 "scale {} is greater than max {}",
1564 scale,
1565 T::MAX_SCALE
1566 )));
1567 }
1568 if scale > 0 && scale as u8 > precision {
1569 return Err(ArrowError::InvalidArgumentError(format!(
1570 "scale {scale} is greater than precision {precision}"
1571 )));
1572 }
1573
1574 Ok(())
1575}
1576
1577#[derive(Debug)]
1579pub struct Decimal32Type {}
1580
1581impl DecimalType for Decimal32Type {
1582 const BYTE_LENGTH: usize = 4;
1583 const MAX_PRECISION: u8 = DECIMAL32_MAX_PRECISION;
1584 const MAX_SCALE: i8 = DECIMAL32_MAX_SCALE;
1585 const MAX_FOR_EACH_PRECISION: &'static [i32] =
1586 &arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
1587 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1588 const DEFAULT_TYPE: DataType =
1589 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1590 const PREFIX: &'static str = "Decimal32";
1591
1592 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1593 format_decimal_str(&value.to_string(), precision as usize, scale)
1594 }
1595
1596 fn validate_decimal_precision(num: i32, precision: u8, scale: i8) -> Result<(), ArrowError> {
1597 validate_decimal32_precision(num, precision, scale)
1598 }
1599
1600 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1601 is_validate_decimal32_precision(value, precision)
1602 }
1603}
1604
1605impl ArrowPrimitiveType for Decimal32Type {
1606 type Native = i32;
1607
1608 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1609}
1610
1611impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1612
1613#[derive(Debug)]
1615pub struct Decimal64Type {}
1616
1617impl DecimalType for Decimal64Type {
1618 const BYTE_LENGTH: usize = 8;
1619 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1620 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1621 const MAX_FOR_EACH_PRECISION: &'static [i64] =
1622 &arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
1623 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1624 const DEFAULT_TYPE: DataType =
1625 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1626 const PREFIX: &'static str = "Decimal64";
1627
1628 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1629 format_decimal_str(&value.to_string(), precision as usize, scale)
1630 }
1631
1632 fn validate_decimal_precision(num: i64, precision: u8, scale: i8) -> Result<(), ArrowError> {
1633 validate_decimal64_precision(num, precision, scale)
1634 }
1635
1636 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1637 is_validate_decimal64_precision(value, precision)
1638 }
1639}
1640
1641impl ArrowPrimitiveType for Decimal64Type {
1642 type Native = i64;
1643
1644 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1645}
1646
1647impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1648
1649#[derive(Debug)]
1651pub struct Decimal128Type {}
1652
1653impl DecimalType for Decimal128Type {
1654 const BYTE_LENGTH: usize = 16;
1655 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1656 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1657 const MAX_FOR_EACH_PRECISION: &'static [i128] =
1658 &arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
1659 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1660 const DEFAULT_TYPE: DataType =
1661 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1662 const PREFIX: &'static str = "Decimal128";
1663
1664 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1665 format_decimal_str(&value.to_string(), precision as usize, scale)
1666 }
1667
1668 fn validate_decimal_precision(num: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1669 validate_decimal_precision(num, precision, scale)
1670 }
1671
1672 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1673 is_validate_decimal_precision(value, precision)
1674 }
1675}
1676
1677impl ArrowPrimitiveType for Decimal128Type {
1678 type Native = i128;
1679
1680 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1681}
1682
1683impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1684
1685#[derive(Debug)]
1687pub struct Decimal256Type {}
1688
1689impl DecimalType for Decimal256Type {
1690 const BYTE_LENGTH: usize = 32;
1691 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1692 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1693 const MAX_FOR_EACH_PRECISION: &'static [i256] =
1694 &arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
1695 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1696 const DEFAULT_TYPE: DataType =
1697 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1698 const PREFIX: &'static str = "Decimal256";
1699
1700 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1701 format_decimal_str(&value.to_string(), precision as usize, scale)
1702 }
1703
1704 fn validate_decimal_precision(num: i256, precision: u8, scale: i8) -> Result<(), ArrowError> {
1705 validate_decimal256_precision(num, precision, scale)
1706 }
1707
1708 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1709 is_validate_decimal256_precision(value, precision)
1710 }
1711}
1712
1713impl ArrowPrimitiveType for Decimal256Type {
1714 type Native = i256;
1715
1716 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1717}
1718
1719impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1720
1721pub(crate) mod bytes {
1725 use super::*;
1726
1727 pub trait ByteArrayTypeSealed {}
1728 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1729 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1730
1731 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1732 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1733
1734 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1738 }
1739
1740 impl ByteArrayNativeType for [u8] {
1741 #[inline]
1742 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1743 Some(b)
1744 }
1745
1746 #[inline]
1747 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1748 b
1749 }
1750 }
1751
1752 impl ByteArrayNativeType for str {
1753 #[inline]
1754 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1755 std::str::from_utf8(b).ok()
1756 }
1757
1758 #[inline]
1759 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1760 unsafe { std::str::from_utf8_unchecked(b) }
1761 }
1762 }
1763}
1764
1765pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1769 type Offset: OffsetSizeTrait;
1771 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1775
1776 const PREFIX: &'static str;
1778
1779 const DATA_TYPE: DataType;
1781
1782 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1784}
1785
1786pub struct GenericStringType<O: OffsetSizeTrait> {
1788 phantom: PhantomData<O>,
1789}
1790
1791impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1792 type Offset = O;
1793 type Native = str;
1794 const PREFIX: &'static str = "String";
1795
1796 const DATA_TYPE: DataType = if O::IS_LARGE {
1797 DataType::LargeUtf8
1798 } else {
1799 DataType::Utf8
1800 };
1801
1802 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1803 let validated = std::str::from_utf8(values).map_err(|e| {
1805 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1806 })?;
1807
1808 for offset in offsets.iter() {
1810 let o = offset.as_usize();
1811 if !validated.is_char_boundary(o) {
1812 if o < validated.len() {
1813 return Err(ArrowError::InvalidArgumentError(format!(
1814 "Split UTF-8 codepoint at offset {o}"
1815 )));
1816 }
1817 return Err(ArrowError::InvalidArgumentError(format!(
1818 "Offset of {o} exceeds length of values {}",
1819 validated.len()
1820 )));
1821 }
1822 }
1823 Ok(())
1824 }
1825}
1826
1827pub type Utf8Type = GenericStringType<i32>;
1829pub type LargeUtf8Type = GenericStringType<i64>;
1831
1832pub struct GenericBinaryType<O: OffsetSizeTrait> {
1834 phantom: PhantomData<O>,
1835}
1836
1837impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1838 type Offset = O;
1839 type Native = [u8];
1840 const PREFIX: &'static str = "Binary";
1841
1842 const DATA_TYPE: DataType = if O::IS_LARGE {
1843 DataType::LargeBinary
1844 } else {
1845 DataType::Binary
1846 };
1847
1848 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1849 let max_offset = offsets.last().unwrap().as_usize();
1851 if values.len() < max_offset {
1852 return Err(ArrowError::InvalidArgumentError(format!(
1853 "Maximum offset of {max_offset} is larger than values of length {}",
1854 values.len()
1855 )));
1856 }
1857 Ok(())
1858 }
1859}
1860
1861pub type BinaryType = GenericBinaryType<i32>;
1863pub type LargeBinaryType = GenericBinaryType<i64>;
1865
1866mod byte_view {
1867 use crate::types::{BinaryViewType, StringViewType};
1868
1869 pub trait Sealed: Send + Sync {}
1870 impl Sealed for StringViewType {}
1871 impl Sealed for BinaryViewType {}
1872}
1873
1874pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1876 const IS_UTF8: bool;
1878
1879 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1881 DataType::Utf8View
1882 } else {
1883 DataType::BinaryView
1884 };
1885
1886 const PREFIX: &'static str;
1888
1889 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1893
1894 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1896
1897 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1899}
1900
1901#[derive(PartialEq)]
1903pub struct StringViewType {}
1904
1905impl ByteViewType for StringViewType {
1906 const IS_UTF8: bool = true;
1907 const PREFIX: &'static str = "String";
1908
1909 type Native = str;
1910 type Owned = String;
1911
1912 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1913 validate_string_view(views, buffers)
1914 }
1915}
1916
1917#[derive(PartialEq)]
1919pub struct BinaryViewType {}
1920
1921impl ByteViewType for BinaryViewType {
1922 const IS_UTF8: bool = false;
1923 const PREFIX: &'static str = "Binary";
1924 type Native = [u8];
1925 type Owned = Vec<u8>;
1926
1927 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1928 validate_binary_view(views, buffers)
1929 }
1930}
1931
1932#[cfg(test)]
1933mod tests {
1934 use super::*;
1935 use arrow_data::{BufferSpec, layout};
1936 use chrono::DateTime;
1937
1938 #[test]
1939 fn month_day_nano_should_roundtrip() {
1940 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1941 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1942 }
1943
1944 #[test]
1945 fn month_day_nano_should_roundtrip_neg() {
1946 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1947 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1948 }
1949
1950 #[test]
1951 fn day_time_should_roundtrip() {
1952 let value = IntervalDayTimeType::make_value(1, 2);
1953 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1954 }
1955
1956 #[test]
1957 fn day_time_should_roundtrip_neg() {
1958 let value = IntervalDayTimeType::make_value(-1, -2);
1959 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1960 }
1961
1962 #[test]
1963 fn year_month_should_roundtrip() {
1964 let value = IntervalYearMonthType::make_value(1, 2);
1965 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1966 }
1967
1968 #[test]
1969 fn year_month_should_roundtrip_neg() {
1970 let value = IntervalYearMonthType::make_value(-1, -2);
1971 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1972 }
1973
1974 fn test_layout<T: ArrowPrimitiveType>() {
1975 let layout = layout(&T::DATA_TYPE);
1976
1977 assert_eq!(layout.buffers.len(), 1);
1978
1979 let spec = &layout.buffers[0];
1980 assert_eq!(
1981 spec,
1982 &BufferSpec::FixedWidth {
1983 byte_width: std::mem::size_of::<T::Native>(),
1984 alignment: std::mem::align_of::<T::Native>(),
1985 }
1986 );
1987 }
1988
1989 #[test]
1990 fn test_layouts() {
1991 test_layout::<Int8Type>();
1992 test_layout::<Int16Type>();
1993 test_layout::<Int32Type>();
1994 test_layout::<Int64Type>();
1995 test_layout::<UInt8Type>();
1996 test_layout::<UInt16Type>();
1997 test_layout::<UInt32Type>();
1998 test_layout::<UInt64Type>();
1999 test_layout::<Float16Type>();
2000 test_layout::<Float32Type>();
2001 test_layout::<Float64Type>();
2002 test_layout::<Decimal32Type>();
2003 test_layout::<Decimal64Type>();
2004 test_layout::<Decimal128Type>();
2005 test_layout::<Decimal256Type>();
2006 test_layout::<TimestampNanosecondType>();
2007 test_layout::<TimestampMillisecondType>();
2008 test_layout::<TimestampMicrosecondType>();
2009 test_layout::<TimestampNanosecondType>();
2010 test_layout::<TimestampSecondType>();
2011 test_layout::<Date32Type>();
2012 test_layout::<Date64Type>();
2013 test_layout::<Time32SecondType>();
2014 test_layout::<Time32MillisecondType>();
2015 test_layout::<Time64MicrosecondType>();
2016 test_layout::<Time64NanosecondType>();
2017 test_layout::<IntervalMonthDayNanoType>();
2018 test_layout::<IntervalDayTimeType>();
2019 test_layout::<IntervalYearMonthType>();
2020 test_layout::<DurationNanosecondType>();
2021 test_layout::<DurationMicrosecondType>();
2022 test_layout::<DurationMillisecondType>();
2023 test_layout::<DurationSecondType>();
2024 }
2025
2026 #[test]
2027 fn timestamp_from_datetime() {
2028 use chrono::{FixedOffset, NaiveDate, NaiveTime, Utc};
2029
2030 let date = NaiveDate::from_ymd_opt(2021, 1, 1).unwrap();
2032 let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
2033 let naive = NaiveDateTime::new(date, time);
2034 let datetime_utc = Utc.from_utc_datetime(&naive);
2035
2036 assert_eq!(
2037 TimestampSecondType::from_datetime(datetime_utc).unwrap(),
2038 1609502400
2039 );
2040 assert_eq!(
2041 TimestampMillisecondType::from_datetime(datetime_utc).unwrap(),
2042 1609502400000
2043 );
2044 assert_eq!(
2045 TimestampMicrosecondType::from_datetime(datetime_utc).unwrap(),
2046 1609502400000000
2047 );
2048 assert_eq!(
2049 TimestampNanosecondType::from_datetime(datetime_utc).unwrap(),
2050 1609502400000000000
2051 );
2052
2053 let tz_plus_8 = FixedOffset::east_opt(8 * 3600).unwrap();
2055 let datetime_plus_8 = tz_plus_8.from_local_datetime(&naive).unwrap();
2056 assert_eq!(
2057 TimestampSecondType::from_datetime(datetime_plus_8).unwrap(),
2058 1609502400 - 28800
2059 );
2060
2061 let datetime = DateTime::from_timestamp(1000000000, 123456789).unwrap();
2063 assert_eq!(
2064 TimestampSecondType::from_datetime(datetime).unwrap(),
2065 1000000000
2066 );
2067 assert_eq!(
2068 TimestampMillisecondType::from_datetime(datetime).unwrap(),
2069 1000000000123
2070 );
2071 assert_eq!(
2072 TimestampMicrosecondType::from_datetime(datetime).unwrap(),
2073 1000000000123456
2074 );
2075 assert_eq!(
2076 TimestampNanosecondType::from_datetime(datetime).unwrap(),
2077 1000000000123456789
2078 );
2079 }
2080
2081 #[test]
2082 fn timestamp_from_datetime_overflow() {
2083 let far_past = DateTime::from_timestamp(-10_000_000_000, 0).unwrap();
2085 assert!(TimestampNanosecondType::from_datetime(far_past).is_none());
2086 assert!(TimestampSecondType::from_datetime(far_past).is_some());
2088 assert!(TimestampMillisecondType::from_datetime(far_past).is_some());
2089 assert!(TimestampMicrosecondType::from_datetime(far_past).is_some());
2090
2091 let far_future = DateTime::from_timestamp(10_000_000_000, 0).unwrap();
2092 assert!(TimestampNanosecondType::from_datetime(far_future).is_none());
2093 assert!(TimestampSecondType::from_datetime(far_future).is_some());
2094 assert!(TimestampMillisecondType::from_datetime(far_future).is_some());
2095 assert!(TimestampMicrosecondType::from_datetime(far_future).is_some());
2096 }
2097
2098 #[test]
2099 fn timestamp_from_naive_datetime() {
2100 use crate::temporal_conversions::as_datetime_with_timezone;
2101 use chrono::{NaiveDate, NaiveTime};
2102
2103 let date = NaiveDate::from_ymd_opt(2021, 1, 1).unwrap();
2104 let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
2105 let naive = NaiveDateTime::new(date, time);
2106
2107 assert_eq!(
2109 TimestampSecondType::from_naive_datetime(naive, None).unwrap(),
2110 1609502400
2111 );
2112 assert_eq!(
2113 TimestampMillisecondType::from_naive_datetime(naive, None).unwrap(),
2114 1609502400000
2115 );
2116
2117 let tz: Tz = "-05:00".parse().unwrap();
2119 let ts_sec = TimestampSecondType::from_naive_datetime(naive, Some(&tz)).unwrap();
2120 assert_eq!(ts_sec, 1609502400 + 5 * 3600);
2121
2122 let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();
2124 let time = NaiveTime::from_hms_opt(14, 30, 45).unwrap();
2125 let naive = NaiveDateTime::new(date, time);
2126 let tz: Tz = "+01:00".parse().unwrap();
2127
2128 let ts_usec = TimestampMicrosecondType::from_naive_datetime(naive, Some(&tz)).unwrap();
2129 let recovered = as_datetime_with_timezone::<TimestampMicrosecondType>(ts_usec, tz).unwrap();
2130 assert_eq!(recovered.naive_local(), naive);
2131 }
2132
2133 #[test]
2134 #[cfg(feature = "chrono-tz")]
2135 fn timestamp_from_naive_datetime_ambiguous() {
2136 use chrono::{NaiveDate, NaiveTime};
2137
2138 let date = NaiveDate::from_ymd_opt(2024, 11, 3).unwrap();
2141 let time = NaiveTime::from_hms_opt(1, 30, 0).unwrap();
2142 let naive = NaiveDateTime::new(date, time);
2143 let tz: Tz = "America/New_York".parse().unwrap();
2144
2145 let result = TimestampSecondType::from_naive_datetime(naive, Some(&tz));
2147 assert!(result.is_some());
2148 assert_eq!(result.unwrap(), 1730611800);
2149 }
2150
2151 #[test]
2152 #[cfg(feature = "chrono-tz")]
2153 fn timestamp_from_naive_datetime_none() {
2154 use chrono::{NaiveDate, NaiveTime};
2155
2156 let date = NaiveDate::from_ymd_opt(2024, 3, 10).unwrap();
2159 let time = NaiveTime::from_hms_opt(2, 30, 0).unwrap();
2160 let naive = NaiveDateTime::new(date, time);
2161 let tz: Tz = "America/New_York".parse().unwrap();
2162
2163 let result = TimestampSecondType::from_naive_datetime(naive, Some(&tz));
2165 assert!(result.is_none());
2166
2167 assert!(TimestampMillisecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2169 assert!(TimestampMicrosecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2170 assert!(TimestampNanosecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2171 }
2172}