1use crate::delta::{
21 add_days_datetime, add_months_datetime, shift_months, 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::{i256, Buffer, OffsetBuffer};
27use arrow_data::decimal::{
28 is_validate_decimal256_precision, is_validate_decimal_precision, validate_decimal256_precision,
29 validate_decimal_precision,
30};
31use arrow_data::{validate_binary_view, validate_string_view};
32use arrow_schema::{
33 ArrowError, DataType, IntervalUnit, TimeUnit, DECIMAL128_MAX_PRECISION, DECIMAL128_MAX_SCALE,
34 DECIMAL256_MAX_PRECISION, DECIMAL256_MAX_SCALE, DECIMAL_DEFAULT_SCALE,
35};
36use chrono::{Duration, NaiveDate, NaiveDateTime};
37use half::f16;
38use std::fmt::Debug;
39use std::marker::PhantomData;
40use std::ops::{Add, Sub};
41
42pub use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
44
45#[derive(Debug)]
49pub struct BooleanType {}
50
51impl BooleanType {
52 pub const DATA_TYPE: DataType = DataType::Boolean;
54}
55
56pub trait ArrowPrimitiveType: primitive::PrimitiveTypeSealed + 'static {
65 type Native: ArrowNativeTypeOp;
67
68 const DATA_TYPE: DataType;
70
71 #[deprecated(note = "Use ArrowNativeType::get_byte_width")]
73 fn get_byte_width() -> usize {
74 std::mem::size_of::<Self::Native>()
75 }
76
77 fn default_value() -> Self::Native {
81 Default::default()
82 }
83}
84
85mod primitive {
86 pub trait PrimitiveTypeSealed {}
87}
88
89macro_rules! make_type {
90 ($name:ident, $native_ty:ty, $data_ty:expr, $doc_string: literal) => {
91 #[derive(Debug)]
92 #[doc = $doc_string]
93 pub struct $name {}
94
95 impl ArrowPrimitiveType for $name {
96 type Native = $native_ty;
97 const DATA_TYPE: DataType = $data_ty;
98 }
99
100 impl primitive::PrimitiveTypeSealed for $name {}
101 };
102}
103
104make_type!(Int8Type, i8, DataType::Int8, "A signed 8-bit integer type.");
105make_type!(
106 Int16Type,
107 i16,
108 DataType::Int16,
109 "Signed 16-bit integer type."
110);
111make_type!(
112 Int32Type,
113 i32,
114 DataType::Int32,
115 "Signed 32-bit integer type."
116);
117make_type!(
118 Int64Type,
119 i64,
120 DataType::Int64,
121 "Signed 64-bit integer type."
122);
123make_type!(
124 UInt8Type,
125 u8,
126 DataType::UInt8,
127 "Unsigned 8-bit integer type."
128);
129make_type!(
130 UInt16Type,
131 u16,
132 DataType::UInt16,
133 "Unsigned 16-bit integer type."
134);
135make_type!(
136 UInt32Type,
137 u32,
138 DataType::UInt32,
139 "Unsigned 32-bit integer type."
140);
141make_type!(
142 UInt64Type,
143 u64,
144 DataType::UInt64,
145 "Unsigned 64-bit integer type."
146);
147make_type!(
148 Float16Type,
149 f16,
150 DataType::Float16,
151 "16-bit floating point number type."
152);
153make_type!(
154 Float32Type,
155 f32,
156 DataType::Float32,
157 "32-bit floating point number type."
158);
159make_type!(
160 Float64Type,
161 f64,
162 DataType::Float64,
163 "64-bit floating point number type."
164);
165make_type!(
166 TimestampSecondType,
167 i64,
168 DataType::Timestamp(TimeUnit::Second, None),
169 "Timestamp second type with an optional timezone."
170);
171make_type!(
172 TimestampMillisecondType,
173 i64,
174 DataType::Timestamp(TimeUnit::Millisecond, None),
175 "Timestamp millisecond type with an optional timezone."
176);
177make_type!(
178 TimestampMicrosecondType,
179 i64,
180 DataType::Timestamp(TimeUnit::Microsecond, None),
181 "Timestamp microsecond type with an optional timezone."
182);
183make_type!(
184 TimestampNanosecondType,
185 i64,
186 DataType::Timestamp(TimeUnit::Nanosecond, None),
187 "Timestamp nanosecond type with an optional timezone."
188);
189make_type!(
190 Date32Type,
191 i32,
192 DataType::Date32,
193 "32-bit date type: the elapsed time since UNIX epoch in days (32 bits)."
194);
195make_type!(
196 Date64Type,
197 i64,
198 DataType::Date64,
199 "64-bit date type: the elapsed time since UNIX epoch in milliseconds (64 bits). \
200 Values must be divisible by `86_400_000`. \
201 See [`DataType::Date64`] for more details."
202);
203make_type!(
204 Time32SecondType,
205 i32,
206 DataType::Time32(TimeUnit::Second),
207 "32-bit time type: the elapsed time since midnight in seconds."
208);
209make_type!(
210 Time32MillisecondType,
211 i32,
212 DataType::Time32(TimeUnit::Millisecond),
213 "32-bit time type: the elapsed time since midnight in milliseconds."
214);
215make_type!(
216 Time64MicrosecondType,
217 i64,
218 DataType::Time64(TimeUnit::Microsecond),
219 "64-bit time type: the elapsed time since midnight in microseconds."
220);
221make_type!(
222 Time64NanosecondType,
223 i64,
224 DataType::Time64(TimeUnit::Nanosecond),
225 "64-bit time type: the elapsed time since midnight in nanoseconds."
226);
227make_type!(
228 IntervalYearMonthType,
229 i32,
230 DataType::Interval(IntervalUnit::YearMonth),
231 "32-bit “calendar” interval type: the number of whole months."
232);
233make_type!(
234 IntervalDayTimeType,
235 IntervalDayTime,
236 DataType::Interval(IntervalUnit::DayTime),
237 "“Calendar” interval type: days and milliseconds. See [`IntervalDayTime`] for more details."
238);
239make_type!(
240 IntervalMonthDayNanoType,
241 IntervalMonthDayNano,
242 DataType::Interval(IntervalUnit::MonthDayNano),
243 r"“Calendar” interval type: months, days, and nanoseconds. See [`IntervalMonthDayNano`] for more details."
244);
245make_type!(
246 DurationSecondType,
247 i64,
248 DataType::Duration(TimeUnit::Second),
249 "Elapsed time type: seconds."
250);
251make_type!(
252 DurationMillisecondType,
253 i64,
254 DataType::Duration(TimeUnit::Millisecond),
255 "Elapsed time type: milliseconds."
256);
257make_type!(
258 DurationMicrosecondType,
259 i64,
260 DataType::Duration(TimeUnit::Microsecond),
261 "Elapsed time type: microseconds."
262);
263make_type!(
264 DurationNanosecondType,
265 i64,
266 DataType::Duration(TimeUnit::Nanosecond),
267 "Elapsed time type: nanoseconds."
268);
269
270pub trait ArrowDictionaryKeyType: ArrowPrimitiveType {}
273
274impl ArrowDictionaryKeyType for Int8Type {}
275
276impl ArrowDictionaryKeyType for Int16Type {}
277
278impl ArrowDictionaryKeyType for Int32Type {}
279
280impl ArrowDictionaryKeyType for Int64Type {}
281
282impl ArrowDictionaryKeyType for UInt8Type {}
283
284impl ArrowDictionaryKeyType for UInt16Type {}
285
286impl ArrowDictionaryKeyType for UInt32Type {}
287
288impl ArrowDictionaryKeyType for UInt64Type {}
289
290pub trait RunEndIndexType: ArrowPrimitiveType {}
294
295impl RunEndIndexType for Int16Type {}
296
297impl RunEndIndexType for Int32Type {}
298
299impl RunEndIndexType for Int64Type {}
300
301pub trait ArrowTemporalType: ArrowPrimitiveType {}
303
304impl ArrowTemporalType for TimestampSecondType {}
305impl ArrowTemporalType for TimestampMillisecondType {}
306impl ArrowTemporalType for TimestampMicrosecondType {}
307impl ArrowTemporalType for TimestampNanosecondType {}
308impl ArrowTemporalType for Date32Type {}
309impl ArrowTemporalType for Date64Type {}
310impl ArrowTemporalType for Time32SecondType {}
311impl ArrowTemporalType for Time32MillisecondType {}
312impl ArrowTemporalType for Time64MicrosecondType {}
313impl ArrowTemporalType for Time64NanosecondType {}
314impl ArrowTemporalType for DurationSecondType {}
318impl ArrowTemporalType for DurationMillisecondType {}
319impl ArrowTemporalType for DurationMicrosecondType {}
320impl ArrowTemporalType for DurationNanosecondType {}
321
322pub trait ArrowTimestampType: ArrowTemporalType<Native = i64> {
324 const UNIT: TimeUnit;
326
327 #[deprecated(note = "Use Self::UNIT")]
329 fn get_time_unit() -> TimeUnit {
330 Self::UNIT
331 }
332
333 fn make_value(naive: NaiveDateTime) -> Option<i64>;
337}
338
339impl ArrowTimestampType for TimestampSecondType {
340 const UNIT: TimeUnit = TimeUnit::Second;
341
342 fn make_value(naive: NaiveDateTime) -> Option<i64> {
343 Some(naive.and_utc().timestamp())
344 }
345}
346impl ArrowTimestampType for TimestampMillisecondType {
347 const UNIT: TimeUnit = TimeUnit::Millisecond;
348
349 fn make_value(naive: NaiveDateTime) -> Option<i64> {
350 let utc = naive.and_utc();
351 let millis = utc.timestamp().checked_mul(1_000)?;
352 millis.checked_add(utc.timestamp_subsec_millis() as i64)
353 }
354}
355impl ArrowTimestampType for TimestampMicrosecondType {
356 const UNIT: TimeUnit = TimeUnit::Microsecond;
357
358 fn make_value(naive: NaiveDateTime) -> Option<i64> {
359 let utc = naive.and_utc();
360 let micros = utc.timestamp().checked_mul(1_000_000)?;
361 micros.checked_add(utc.timestamp_subsec_micros() as i64)
362 }
363}
364impl ArrowTimestampType for TimestampNanosecondType {
365 const UNIT: TimeUnit = TimeUnit::Nanosecond;
366
367 fn make_value(naive: NaiveDateTime) -> Option<i64> {
368 let utc = naive.and_utc();
369 let nanos = utc.timestamp().checked_mul(1_000_000_000)?;
370 nanos.checked_add(utc.timestamp_subsec_nanos() as i64)
371 }
372}
373
374fn add_year_months<T: ArrowTimestampType>(
375 timestamp: <T as ArrowPrimitiveType>::Native,
376 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
377 tz: Tz,
378) -> Option<<T as ArrowPrimitiveType>::Native> {
379 let months = IntervalYearMonthType::to_months(delta);
380 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
381 let res = add_months_datetime(res, months)?;
382 let res = res.naive_utc();
383 T::make_value(res)
384}
385
386fn add_day_time<T: ArrowTimestampType>(
387 timestamp: <T as ArrowPrimitiveType>::Native,
388 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
389 tz: Tz,
390) -> Option<<T as ArrowPrimitiveType>::Native> {
391 let (days, ms) = IntervalDayTimeType::to_parts(delta);
392 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
393 let res = add_days_datetime(res, days)?;
394 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
395 let res = res.naive_utc();
396 T::make_value(res)
397}
398
399fn add_month_day_nano<T: ArrowTimestampType>(
400 timestamp: <T as ArrowPrimitiveType>::Native,
401 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
402 tz: Tz,
403) -> Option<<T as ArrowPrimitiveType>::Native> {
404 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
405 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
406 let res = add_months_datetime(res, months)?;
407 let res = add_days_datetime(res, days)?;
408 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
409 let res = res.naive_utc();
410 T::make_value(res)
411}
412
413fn subtract_year_months<T: ArrowTimestampType>(
414 timestamp: <T as ArrowPrimitiveType>::Native,
415 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
416 tz: Tz,
417) -> Option<<T as ArrowPrimitiveType>::Native> {
418 let months = IntervalYearMonthType::to_months(delta);
419 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
420 let res = sub_months_datetime(res, months)?;
421 let res = res.naive_utc();
422 T::make_value(res)
423}
424
425fn subtract_day_time<T: ArrowTimestampType>(
426 timestamp: <T as ArrowPrimitiveType>::Native,
427 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
428 tz: Tz,
429) -> Option<<T as ArrowPrimitiveType>::Native> {
430 let (days, ms) = IntervalDayTimeType::to_parts(delta);
431 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
432 let res = sub_days_datetime(res, days)?;
433 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
434 let res = res.naive_utc();
435 T::make_value(res)
436}
437
438fn subtract_month_day_nano<T: ArrowTimestampType>(
439 timestamp: <T as ArrowPrimitiveType>::Native,
440 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
441 tz: Tz,
442) -> Option<<T as ArrowPrimitiveType>::Native> {
443 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
444 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
445 let res = sub_months_datetime(res, months)?;
446 let res = sub_days_datetime(res, days)?;
447 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
448 let res = res.naive_utc();
449 T::make_value(res)
450}
451
452impl TimestampSecondType {
453 pub fn add_year_months(
463 timestamp: <Self as ArrowPrimitiveType>::Native,
464 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
465 tz: Tz,
466 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
467 add_year_months::<Self>(timestamp, delta, tz)
468 }
469
470 pub fn add_day_time(
480 timestamp: <Self as ArrowPrimitiveType>::Native,
481 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
482 tz: Tz,
483 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
484 add_day_time::<Self>(timestamp, delta, tz)
485 }
486
487 pub fn add_month_day_nano(
496 timestamp: <Self as ArrowPrimitiveType>::Native,
497 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
498 tz: Tz,
499 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
500 add_month_day_nano::<Self>(timestamp, delta, tz)
501 }
502
503 pub fn subtract_year_months(
513 timestamp: <Self as ArrowPrimitiveType>::Native,
514 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
515 tz: Tz,
516 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
517 subtract_year_months::<Self>(timestamp, delta, tz)
518 }
519
520 pub fn subtract_day_time(
530 timestamp: <Self as ArrowPrimitiveType>::Native,
531 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
532 tz: Tz,
533 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
534 subtract_day_time::<Self>(timestamp, delta, tz)
535 }
536
537 pub fn subtract_month_day_nano(
547 timestamp: <Self as ArrowPrimitiveType>::Native,
548 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
549 tz: Tz,
550 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
551 subtract_month_day_nano::<Self>(timestamp, delta, tz)
552 }
553}
554
555impl TimestampMicrosecondType {
556 pub fn add_year_months(
564 timestamp: <Self as ArrowPrimitiveType>::Native,
565 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
566 tz: Tz,
567 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
568 add_year_months::<Self>(timestamp, delta, tz)
569 }
570
571 pub fn add_day_time(
579 timestamp: <Self as ArrowPrimitiveType>::Native,
580 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
581 tz: Tz,
582 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
583 add_day_time::<Self>(timestamp, delta, tz)
584 }
585
586 pub fn add_month_day_nano(
594 timestamp: <Self as ArrowPrimitiveType>::Native,
595 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
596 tz: Tz,
597 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
598 add_month_day_nano::<Self>(timestamp, delta, tz)
599 }
600
601 pub fn subtract_year_months(
609 timestamp: <Self as ArrowPrimitiveType>::Native,
610 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
611 tz: Tz,
612 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
613 subtract_year_months::<Self>(timestamp, delta, tz)
614 }
615
616 pub fn subtract_day_time(
624 timestamp: <Self as ArrowPrimitiveType>::Native,
625 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
626 tz: Tz,
627 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
628 subtract_day_time::<Self>(timestamp, delta, tz)
629 }
630
631 pub fn subtract_month_day_nano(
639 timestamp: <Self as ArrowPrimitiveType>::Native,
640 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
641 tz: Tz,
642 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
643 subtract_month_day_nano::<Self>(timestamp, delta, tz)
644 }
645}
646
647impl TimestampMillisecondType {
648 pub fn add_year_months(
656 timestamp: <Self as ArrowPrimitiveType>::Native,
657 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
658 tz: Tz,
659 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
660 add_year_months::<Self>(timestamp, delta, tz)
661 }
662
663 pub fn add_day_time(
671 timestamp: <Self as ArrowPrimitiveType>::Native,
672 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
673 tz: Tz,
674 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
675 add_day_time::<Self>(timestamp, delta, tz)
676 }
677
678 pub fn add_month_day_nano(
686 timestamp: <Self as ArrowPrimitiveType>::Native,
687 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
688 tz: Tz,
689 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
690 add_month_day_nano::<Self>(timestamp, delta, tz)
691 }
692
693 pub fn subtract_year_months(
701 timestamp: <Self as ArrowPrimitiveType>::Native,
702 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
703 tz: Tz,
704 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
705 subtract_year_months::<Self>(timestamp, delta, tz)
706 }
707
708 pub fn subtract_day_time(
716 timestamp: <Self as ArrowPrimitiveType>::Native,
717 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
718 tz: Tz,
719 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
720 subtract_day_time::<Self>(timestamp, delta, tz)
721 }
722
723 pub fn subtract_month_day_nano(
731 timestamp: <Self as ArrowPrimitiveType>::Native,
732 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
733 tz: Tz,
734 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
735 subtract_month_day_nano::<Self>(timestamp, delta, tz)
736 }
737}
738
739impl TimestampNanosecondType {
740 pub fn add_year_months(
748 timestamp: <Self as ArrowPrimitiveType>::Native,
749 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
750 tz: Tz,
751 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
752 add_year_months::<Self>(timestamp, delta, tz)
753 }
754
755 pub fn add_day_time(
763 timestamp: <Self as ArrowPrimitiveType>::Native,
764 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
765 tz: Tz,
766 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
767 add_day_time::<Self>(timestamp, delta, tz)
768 }
769
770 pub fn add_month_day_nano(
778 timestamp: <Self as ArrowPrimitiveType>::Native,
779 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
780 tz: Tz,
781 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
782 add_month_day_nano::<Self>(timestamp, delta, tz)
783 }
784
785 pub fn subtract_year_months(
793 timestamp: <Self as ArrowPrimitiveType>::Native,
794 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
795 tz: Tz,
796 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
797 subtract_year_months::<Self>(timestamp, delta, tz)
798 }
799
800 pub fn subtract_day_time(
808 timestamp: <Self as ArrowPrimitiveType>::Native,
809 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
810 tz: Tz,
811 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
812 subtract_day_time::<Self>(timestamp, delta, tz)
813 }
814
815 pub fn subtract_month_day_nano(
823 timestamp: <Self as ArrowPrimitiveType>::Native,
824 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
825 tz: Tz,
826 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
827 subtract_month_day_nano::<Self>(timestamp, delta, tz)
828 }
829}
830
831impl IntervalYearMonthType {
832 #[inline]
839 pub fn make_value(
840 years: i32,
841 months: i32,
842 ) -> <IntervalYearMonthType as ArrowPrimitiveType>::Native {
843 years * 12 + months
844 }
845
846 #[inline]
854 pub fn to_months(i: <IntervalYearMonthType as ArrowPrimitiveType>::Native) -> i32 {
855 i
856 }
857}
858
859impl IntervalDayTimeType {
860 #[inline]
867 pub fn make_value(days: i32, milliseconds: i32) -> IntervalDayTime {
868 IntervalDayTime { days, milliseconds }
869 }
870
871 #[inline]
877 pub fn to_parts(i: IntervalDayTime) -> (i32, i32) {
878 (i.days, i.milliseconds)
879 }
880}
881
882impl IntervalMonthDayNanoType {
883 #[inline]
891 pub fn make_value(months: i32, days: i32, nanoseconds: i64) -> IntervalMonthDayNano {
892 IntervalMonthDayNano {
893 months,
894 days,
895 nanoseconds,
896 }
897 }
898
899 #[inline]
905 pub fn to_parts(i: IntervalMonthDayNano) -> (i32, i32, i64) {
906 (i.months, i.days, i.nanoseconds)
907 }
908}
909
910impl Date32Type {
911 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
917 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
918 epoch.add(Duration::try_days(i as i64).unwrap())
919 }
920
921 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
927 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
928 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
929 }
930
931 pub fn add_year_months(
938 date: <Date32Type as ArrowPrimitiveType>::Native,
939 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
940 ) -> <Date32Type as ArrowPrimitiveType>::Native {
941 let prior = Date32Type::to_naive_date(date);
942 let months = IntervalYearMonthType::to_months(delta);
943 let posterior = shift_months(prior, months);
944 Date32Type::from_naive_date(posterior)
945 }
946
947 pub fn add_day_time(
954 date: <Date32Type as ArrowPrimitiveType>::Native,
955 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
956 ) -> <Date32Type as ArrowPrimitiveType>::Native {
957 let (days, ms) = IntervalDayTimeType::to_parts(delta);
958 let res = Date32Type::to_naive_date(date);
959 let res = res.add(Duration::try_days(days as i64).unwrap());
960 let res = res.add(Duration::try_milliseconds(ms as i64).unwrap());
961 Date32Type::from_naive_date(res)
962 }
963
964 pub fn add_month_day_nano(
971 date: <Date32Type as ArrowPrimitiveType>::Native,
972 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
973 ) -> <Date32Type as ArrowPrimitiveType>::Native {
974 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
975 let res = Date32Type::to_naive_date(date);
976 let res = shift_months(res, months);
977 let res = res.add(Duration::try_days(days as i64).unwrap());
978 let res = res.add(Duration::nanoseconds(nanos));
979 Date32Type::from_naive_date(res)
980 }
981
982 pub fn subtract_year_months(
989 date: <Date32Type as ArrowPrimitiveType>::Native,
990 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
991 ) -> <Date32Type as ArrowPrimitiveType>::Native {
992 let prior = Date32Type::to_naive_date(date);
993 let months = IntervalYearMonthType::to_months(-delta);
994 let posterior = shift_months(prior, months);
995 Date32Type::from_naive_date(posterior)
996 }
997
998 pub fn subtract_day_time(
1005 date: <Date32Type as ArrowPrimitiveType>::Native,
1006 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1007 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1008 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1009 let res = Date32Type::to_naive_date(date);
1010 let res = res.sub(Duration::try_days(days as i64).unwrap());
1011 let res = res.sub(Duration::try_milliseconds(ms as i64).unwrap());
1012 Date32Type::from_naive_date(res)
1013 }
1014
1015 pub fn subtract_month_day_nano(
1022 date: <Date32Type as ArrowPrimitiveType>::Native,
1023 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1024 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1025 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1026 let res = Date32Type::to_naive_date(date);
1027 let res = shift_months(res, -months);
1028 let res = res.sub(Duration::try_days(days as i64).unwrap());
1029 let res = res.sub(Duration::nanoseconds(nanos));
1030 Date32Type::from_naive_date(res)
1031 }
1032}
1033
1034impl Date64Type {
1035 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1041 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1042 epoch.add(Duration::try_milliseconds(i).unwrap())
1043 }
1044
1045 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1051 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1052 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1053 }
1054
1055 pub fn add_year_months(
1062 date: <Date64Type as ArrowPrimitiveType>::Native,
1063 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1064 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1065 let prior = Date64Type::to_naive_date(date);
1066 let months = IntervalYearMonthType::to_months(delta);
1067 let posterior = shift_months(prior, months);
1068 Date64Type::from_naive_date(posterior)
1069 }
1070
1071 pub fn add_day_time(
1078 date: <Date64Type as ArrowPrimitiveType>::Native,
1079 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1080 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1081 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1082 let res = Date64Type::to_naive_date(date);
1083 let res = res.add(Duration::try_days(days as i64).unwrap());
1084 let res = res.add(Duration::try_milliseconds(ms as i64).unwrap());
1085 Date64Type::from_naive_date(res)
1086 }
1087
1088 pub fn add_month_day_nano(
1095 date: <Date64Type as ArrowPrimitiveType>::Native,
1096 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1097 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1098 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1099 let res = Date64Type::to_naive_date(date);
1100 let res = shift_months(res, months);
1101 let res = res.add(Duration::try_days(days as i64).unwrap());
1102 let res = res.add(Duration::nanoseconds(nanos));
1103 Date64Type::from_naive_date(res)
1104 }
1105
1106 pub fn subtract_year_months(
1113 date: <Date64Type as ArrowPrimitiveType>::Native,
1114 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1115 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1116 let prior = Date64Type::to_naive_date(date);
1117 let months = IntervalYearMonthType::to_months(-delta);
1118 let posterior = shift_months(prior, months);
1119 Date64Type::from_naive_date(posterior)
1120 }
1121
1122 pub fn subtract_day_time(
1129 date: <Date64Type as ArrowPrimitiveType>::Native,
1130 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1131 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1132 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1133 let res = Date64Type::to_naive_date(date);
1134 let res = res.sub(Duration::try_days(days as i64).unwrap());
1135 let res = res.sub(Duration::try_milliseconds(ms as i64).unwrap());
1136 Date64Type::from_naive_date(res)
1137 }
1138
1139 pub fn subtract_month_day_nano(
1146 date: <Date64Type as ArrowPrimitiveType>::Native,
1147 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1148 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1149 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1150 let res = Date64Type::to_naive_date(date);
1151 let res = shift_months(res, -months);
1152 let res = res.sub(Duration::try_days(days as i64).unwrap());
1153 let res = res.sub(Duration::nanoseconds(nanos));
1154 Date64Type::from_naive_date(res)
1155 }
1156}
1157
1158mod decimal {
1162 use super::*;
1163
1164 pub trait DecimalTypeSealed {}
1165 impl DecimalTypeSealed for Decimal128Type {}
1166 impl DecimalTypeSealed for Decimal256Type {}
1167}
1168
1169pub trait DecimalType:
1179 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1180{
1181 const BYTE_LENGTH: usize;
1183 const MAX_PRECISION: u8;
1185 const MAX_SCALE: i8;
1187 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1189 const DEFAULT_TYPE: DataType;
1191
1192 const PREFIX: &'static str;
1194
1195 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1197
1198 fn validate_decimal_precision(value: Self::Native, precision: u8) -> Result<(), ArrowError>;
1200
1201 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1203}
1204
1205pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1213 precision: u8,
1214 scale: i8,
1215) -> Result<(), ArrowError> {
1216 if precision == 0 {
1217 return Err(ArrowError::InvalidArgumentError(format!(
1218 "precision cannot be 0, has to be between [1, {}]",
1219 T::MAX_PRECISION
1220 )));
1221 }
1222 if precision > T::MAX_PRECISION {
1223 return Err(ArrowError::InvalidArgumentError(format!(
1224 "precision {} is greater than max {}",
1225 precision,
1226 T::MAX_PRECISION
1227 )));
1228 }
1229 if scale > T::MAX_SCALE {
1230 return Err(ArrowError::InvalidArgumentError(format!(
1231 "scale {} is greater than max {}",
1232 scale,
1233 T::MAX_SCALE
1234 )));
1235 }
1236 if scale > 0 && scale as u8 > precision {
1237 return Err(ArrowError::InvalidArgumentError(format!(
1238 "scale {scale} is greater than precision {precision}"
1239 )));
1240 }
1241
1242 Ok(())
1243}
1244
1245#[derive(Debug)]
1247pub struct Decimal128Type {}
1248
1249impl DecimalType for Decimal128Type {
1250 const BYTE_LENGTH: usize = 16;
1251 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1252 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1253 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1254 const DEFAULT_TYPE: DataType =
1255 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1256 const PREFIX: &'static str = "Decimal128";
1257
1258 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1259 format_decimal_str(&value.to_string(), precision as usize, scale)
1260 }
1261
1262 fn validate_decimal_precision(num: i128, precision: u8) -> Result<(), ArrowError> {
1263 validate_decimal_precision(num, precision)
1264 }
1265
1266 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1267 is_validate_decimal_precision(value, precision)
1268 }
1269}
1270
1271impl ArrowPrimitiveType for Decimal128Type {
1272 type Native = i128;
1273
1274 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1275}
1276
1277impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1278
1279#[derive(Debug)]
1281pub struct Decimal256Type {}
1282
1283impl DecimalType for Decimal256Type {
1284 const BYTE_LENGTH: usize = 32;
1285 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1286 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1287 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1288 const DEFAULT_TYPE: DataType =
1289 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1290 const PREFIX: &'static str = "Decimal256";
1291
1292 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1293 format_decimal_str(&value.to_string(), precision as usize, scale)
1294 }
1295
1296 fn validate_decimal_precision(num: i256, precision: u8) -> Result<(), ArrowError> {
1297 validate_decimal256_precision(num, precision)
1298 }
1299
1300 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1301 is_validate_decimal256_precision(value, precision)
1302 }
1303}
1304
1305impl ArrowPrimitiveType for Decimal256Type {
1306 type Native = i256;
1307
1308 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1309}
1310
1311impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1312
1313fn format_decimal_str(value_str: &str, precision: usize, scale: i8) -> String {
1314 let (sign, rest) = match value_str.strip_prefix('-') {
1315 Some(stripped) => ("-", stripped),
1316 None => ("", value_str),
1317 };
1318 let bound = precision.min(rest.len()) + sign.len();
1319 let value_str = &value_str[0..bound];
1320
1321 if scale == 0 {
1322 value_str.to_string()
1323 } else if scale < 0 {
1324 let padding = value_str.len() + scale.unsigned_abs() as usize;
1325 format!("{value_str:0<padding$}")
1326 } else if rest.len() > scale as usize {
1327 let (whole, decimal) = value_str.split_at(value_str.len() - scale as usize);
1329 format!("{whole}.{decimal}")
1330 } else {
1331 format!("{}0.{:0>width$}", sign, rest, width = scale as usize)
1333 }
1334}
1335
1336pub(crate) mod bytes {
1340 use super::*;
1341
1342 pub trait ByteArrayTypeSealed {}
1343 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1344 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1345
1346 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1347 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1348
1349 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1353 }
1354
1355 impl ByteArrayNativeType for [u8] {
1356 #[inline]
1357 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1358 Some(b)
1359 }
1360
1361 #[inline]
1362 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1363 b
1364 }
1365 }
1366
1367 impl ByteArrayNativeType for str {
1368 #[inline]
1369 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1370 std::str::from_utf8(b).ok()
1371 }
1372
1373 #[inline]
1374 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1375 std::str::from_utf8_unchecked(b)
1376 }
1377 }
1378}
1379
1380pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1384 type Offset: OffsetSizeTrait;
1386 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1390
1391 const PREFIX: &'static str;
1393
1394 const DATA_TYPE: DataType;
1396
1397 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1399}
1400
1401pub struct GenericStringType<O: OffsetSizeTrait> {
1403 phantom: PhantomData<O>,
1404}
1405
1406impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1407 type Offset = O;
1408 type Native = str;
1409 const PREFIX: &'static str = "String";
1410
1411 const DATA_TYPE: DataType = if O::IS_LARGE {
1412 DataType::LargeUtf8
1413 } else {
1414 DataType::Utf8
1415 };
1416
1417 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1418 let validated = std::str::from_utf8(values).map_err(|e| {
1420 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1421 })?;
1422
1423 for offset in offsets.iter() {
1425 let o = offset.as_usize();
1426 if !validated.is_char_boundary(o) {
1427 if o < validated.len() {
1428 return Err(ArrowError::InvalidArgumentError(format!(
1429 "Split UTF-8 codepoint at offset {o}"
1430 )));
1431 }
1432 return Err(ArrowError::InvalidArgumentError(format!(
1433 "Offset of {o} exceeds length of values {}",
1434 validated.len()
1435 )));
1436 }
1437 }
1438 Ok(())
1439 }
1440}
1441
1442pub type Utf8Type = GenericStringType<i32>;
1444pub type LargeUtf8Type = GenericStringType<i64>;
1446
1447pub struct GenericBinaryType<O: OffsetSizeTrait> {
1449 phantom: PhantomData<O>,
1450}
1451
1452impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1453 type Offset = O;
1454 type Native = [u8];
1455 const PREFIX: &'static str = "Binary";
1456
1457 const DATA_TYPE: DataType = if O::IS_LARGE {
1458 DataType::LargeBinary
1459 } else {
1460 DataType::Binary
1461 };
1462
1463 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1464 let max_offset = offsets.last().unwrap().as_usize();
1466 if values.len() < max_offset {
1467 return Err(ArrowError::InvalidArgumentError(format!(
1468 "Maximum offset of {max_offset} is larger than values of length {}",
1469 values.len()
1470 )));
1471 }
1472 Ok(())
1473 }
1474}
1475
1476pub type BinaryType = GenericBinaryType<i32>;
1478pub type LargeBinaryType = GenericBinaryType<i64>;
1480
1481mod byte_view {
1482 use crate::types::{BinaryViewType, StringViewType};
1483
1484 pub trait Sealed: Send + Sync {}
1485 impl Sealed for StringViewType {}
1486 impl Sealed for BinaryViewType {}
1487}
1488
1489pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1491 const IS_UTF8: bool;
1493
1494 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1496 DataType::Utf8View
1497 } else {
1498 DataType::BinaryView
1499 };
1500
1501 const PREFIX: &'static str;
1503
1504 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1508
1509 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1511
1512 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1514}
1515
1516#[derive(PartialEq)]
1518pub struct StringViewType {}
1519
1520impl ByteViewType for StringViewType {
1521 const IS_UTF8: bool = true;
1522 const PREFIX: &'static str = "String";
1523
1524 type Native = str;
1525 type Owned = String;
1526
1527 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1528 validate_string_view(views, buffers)
1529 }
1530}
1531
1532#[derive(PartialEq)]
1534pub struct BinaryViewType {}
1535
1536impl ByteViewType for BinaryViewType {
1537 const IS_UTF8: bool = false;
1538 const PREFIX: &'static str = "Binary";
1539 type Native = [u8];
1540 type Owned = Vec<u8>;
1541
1542 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1543 validate_binary_view(views, buffers)
1544 }
1545}
1546
1547#[cfg(test)]
1548mod tests {
1549 use super::*;
1550 use arrow_data::{layout, BufferSpec};
1551
1552 #[test]
1553 fn month_day_nano_should_roundtrip() {
1554 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1555 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1556 }
1557
1558 #[test]
1559 fn month_day_nano_should_roundtrip_neg() {
1560 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1561 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1562 }
1563
1564 #[test]
1565 fn day_time_should_roundtrip() {
1566 let value = IntervalDayTimeType::make_value(1, 2);
1567 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1568 }
1569
1570 #[test]
1571 fn day_time_should_roundtrip_neg() {
1572 let value = IntervalDayTimeType::make_value(-1, -2);
1573 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1574 }
1575
1576 #[test]
1577 fn year_month_should_roundtrip() {
1578 let value = IntervalYearMonthType::make_value(1, 2);
1579 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1580 }
1581
1582 #[test]
1583 fn year_month_should_roundtrip_neg() {
1584 let value = IntervalYearMonthType::make_value(-1, -2);
1585 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1586 }
1587
1588 fn test_layout<T: ArrowPrimitiveType>() {
1589 let layout = layout(&T::DATA_TYPE);
1590
1591 assert_eq!(layout.buffers.len(), 1);
1592
1593 let spec = &layout.buffers[0];
1594 assert_eq!(
1595 spec,
1596 &BufferSpec::FixedWidth {
1597 byte_width: std::mem::size_of::<T::Native>(),
1598 alignment: std::mem::align_of::<T::Native>(),
1599 }
1600 );
1601 }
1602
1603 #[test]
1604 fn test_layouts() {
1605 test_layout::<Int8Type>();
1606 test_layout::<Int16Type>();
1607 test_layout::<Int32Type>();
1608 test_layout::<Int64Type>();
1609 test_layout::<UInt8Type>();
1610 test_layout::<UInt16Type>();
1611 test_layout::<UInt32Type>();
1612 test_layout::<UInt64Type>();
1613 test_layout::<Float16Type>();
1614 test_layout::<Float32Type>();
1615 test_layout::<Float64Type>();
1616 test_layout::<Decimal128Type>();
1617 test_layout::<Decimal256Type>();
1618 test_layout::<TimestampNanosecondType>();
1619 test_layout::<TimestampMillisecondType>();
1620 test_layout::<TimestampMicrosecondType>();
1621 test_layout::<TimestampNanosecondType>();
1622 test_layout::<TimestampSecondType>();
1623 test_layout::<Date32Type>();
1624 test_layout::<Date64Type>();
1625 test_layout::<Time32SecondType>();
1626 test_layout::<Time32MillisecondType>();
1627 test_layout::<Time64MicrosecondType>();
1628 test_layout::<Time64NanosecondType>();
1629 test_layout::<IntervalMonthDayNanoType>();
1630 test_layout::<IntervalDayTimeType>();
1631 test_layout::<IntervalYearMonthType>();
1632 test_layout::<DurationNanosecondType>();
1633 test_layout::<DurationMicrosecondType>();
1634 test_layout::<DurationMillisecondType>();
1635 test_layout::<DurationSecondType>();
1636 }
1637}