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(since = "52.0.0", 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 fn make_value(naive: NaiveDateTime) -> Option<i64>;
331}
332
333impl ArrowTimestampType for TimestampSecondType {
334 const UNIT: TimeUnit = TimeUnit::Second;
335
336 fn make_value(naive: NaiveDateTime) -> Option<i64> {
337 Some(naive.and_utc().timestamp())
338 }
339}
340impl ArrowTimestampType for TimestampMillisecondType {
341 const UNIT: TimeUnit = TimeUnit::Millisecond;
342
343 fn make_value(naive: NaiveDateTime) -> Option<i64> {
344 let utc = naive.and_utc();
345 let millis = utc.timestamp().checked_mul(1_000)?;
346 millis.checked_add(utc.timestamp_subsec_millis() as i64)
347 }
348}
349impl ArrowTimestampType for TimestampMicrosecondType {
350 const UNIT: TimeUnit = TimeUnit::Microsecond;
351
352 fn make_value(naive: NaiveDateTime) -> Option<i64> {
353 let utc = naive.and_utc();
354 let micros = utc.timestamp().checked_mul(1_000_000)?;
355 micros.checked_add(utc.timestamp_subsec_micros() as i64)
356 }
357}
358impl ArrowTimestampType for TimestampNanosecondType {
359 const UNIT: TimeUnit = TimeUnit::Nanosecond;
360
361 fn make_value(naive: NaiveDateTime) -> Option<i64> {
362 let utc = naive.and_utc();
363 let nanos = utc.timestamp().checked_mul(1_000_000_000)?;
364 nanos.checked_add(utc.timestamp_subsec_nanos() as i64)
365 }
366}
367
368fn add_year_months<T: ArrowTimestampType>(
369 timestamp: <T as ArrowPrimitiveType>::Native,
370 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
371 tz: Tz,
372) -> Option<<T as ArrowPrimitiveType>::Native> {
373 let months = IntervalYearMonthType::to_months(delta);
374 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
375 let res = add_months_datetime(res, months)?;
376 let res = res.naive_utc();
377 T::make_value(res)
378}
379
380fn add_day_time<T: ArrowTimestampType>(
381 timestamp: <T as ArrowPrimitiveType>::Native,
382 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
383 tz: Tz,
384) -> Option<<T as ArrowPrimitiveType>::Native> {
385 let (days, ms) = IntervalDayTimeType::to_parts(delta);
386 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
387 let res = add_days_datetime(res, days)?;
388 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
389 let res = res.naive_utc();
390 T::make_value(res)
391}
392
393fn add_month_day_nano<T: ArrowTimestampType>(
394 timestamp: <T as ArrowPrimitiveType>::Native,
395 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
396 tz: Tz,
397) -> Option<<T as ArrowPrimitiveType>::Native> {
398 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
399 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
400 let res = add_months_datetime(res, months)?;
401 let res = add_days_datetime(res, days)?;
402 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
403 let res = res.naive_utc();
404 T::make_value(res)
405}
406
407fn subtract_year_months<T: ArrowTimestampType>(
408 timestamp: <T as ArrowPrimitiveType>::Native,
409 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
410 tz: Tz,
411) -> Option<<T as ArrowPrimitiveType>::Native> {
412 let months = IntervalYearMonthType::to_months(delta);
413 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
414 let res = sub_months_datetime(res, months)?;
415 let res = res.naive_utc();
416 T::make_value(res)
417}
418
419fn subtract_day_time<T: ArrowTimestampType>(
420 timestamp: <T as ArrowPrimitiveType>::Native,
421 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
422 tz: Tz,
423) -> Option<<T as ArrowPrimitiveType>::Native> {
424 let (days, ms) = IntervalDayTimeType::to_parts(delta);
425 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
426 let res = sub_days_datetime(res, days)?;
427 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
428 let res = res.naive_utc();
429 T::make_value(res)
430}
431
432fn subtract_month_day_nano<T: ArrowTimestampType>(
433 timestamp: <T as ArrowPrimitiveType>::Native,
434 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
435 tz: Tz,
436) -> Option<<T as ArrowPrimitiveType>::Native> {
437 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
438 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
439 let res = sub_months_datetime(res, months)?;
440 let res = sub_days_datetime(res, days)?;
441 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
442 let res = res.naive_utc();
443 T::make_value(res)
444}
445
446impl TimestampSecondType {
447 pub fn add_year_months(
457 timestamp: <Self as ArrowPrimitiveType>::Native,
458 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
459 tz: Tz,
460 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
461 add_year_months::<Self>(timestamp, delta, tz)
462 }
463
464 pub fn add_day_time(
474 timestamp: <Self as ArrowPrimitiveType>::Native,
475 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
476 tz: Tz,
477 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
478 add_day_time::<Self>(timestamp, delta, tz)
479 }
480
481 pub fn add_month_day_nano(
490 timestamp: <Self as ArrowPrimitiveType>::Native,
491 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
492 tz: Tz,
493 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
494 add_month_day_nano::<Self>(timestamp, delta, tz)
495 }
496
497 pub fn subtract_year_months(
507 timestamp: <Self as ArrowPrimitiveType>::Native,
508 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
509 tz: Tz,
510 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
511 subtract_year_months::<Self>(timestamp, delta, tz)
512 }
513
514 pub fn subtract_day_time(
524 timestamp: <Self as ArrowPrimitiveType>::Native,
525 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
526 tz: Tz,
527 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
528 subtract_day_time::<Self>(timestamp, delta, tz)
529 }
530
531 pub fn subtract_month_day_nano(
541 timestamp: <Self as ArrowPrimitiveType>::Native,
542 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
543 tz: Tz,
544 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
545 subtract_month_day_nano::<Self>(timestamp, delta, tz)
546 }
547}
548
549impl TimestampMicrosecondType {
550 pub fn add_year_months(
558 timestamp: <Self as ArrowPrimitiveType>::Native,
559 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
560 tz: Tz,
561 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
562 add_year_months::<Self>(timestamp, delta, tz)
563 }
564
565 pub fn add_day_time(
573 timestamp: <Self as ArrowPrimitiveType>::Native,
574 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
575 tz: Tz,
576 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
577 add_day_time::<Self>(timestamp, delta, tz)
578 }
579
580 pub fn add_month_day_nano(
588 timestamp: <Self as ArrowPrimitiveType>::Native,
589 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
590 tz: Tz,
591 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
592 add_month_day_nano::<Self>(timestamp, delta, tz)
593 }
594
595 pub fn subtract_year_months(
603 timestamp: <Self as ArrowPrimitiveType>::Native,
604 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
605 tz: Tz,
606 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
607 subtract_year_months::<Self>(timestamp, delta, tz)
608 }
609
610 pub fn subtract_day_time(
618 timestamp: <Self as ArrowPrimitiveType>::Native,
619 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
620 tz: Tz,
621 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
622 subtract_day_time::<Self>(timestamp, delta, tz)
623 }
624
625 pub fn subtract_month_day_nano(
633 timestamp: <Self as ArrowPrimitiveType>::Native,
634 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
635 tz: Tz,
636 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
637 subtract_month_day_nano::<Self>(timestamp, delta, tz)
638 }
639}
640
641impl TimestampMillisecondType {
642 pub fn add_year_months(
650 timestamp: <Self as ArrowPrimitiveType>::Native,
651 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
652 tz: Tz,
653 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
654 add_year_months::<Self>(timestamp, delta, tz)
655 }
656
657 pub fn add_day_time(
665 timestamp: <Self as ArrowPrimitiveType>::Native,
666 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
667 tz: Tz,
668 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
669 add_day_time::<Self>(timestamp, delta, tz)
670 }
671
672 pub fn add_month_day_nano(
680 timestamp: <Self as ArrowPrimitiveType>::Native,
681 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
682 tz: Tz,
683 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
684 add_month_day_nano::<Self>(timestamp, delta, tz)
685 }
686
687 pub fn subtract_year_months(
695 timestamp: <Self as ArrowPrimitiveType>::Native,
696 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
697 tz: Tz,
698 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
699 subtract_year_months::<Self>(timestamp, delta, tz)
700 }
701
702 pub fn subtract_day_time(
710 timestamp: <Self as ArrowPrimitiveType>::Native,
711 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
712 tz: Tz,
713 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
714 subtract_day_time::<Self>(timestamp, delta, tz)
715 }
716
717 pub fn subtract_month_day_nano(
725 timestamp: <Self as ArrowPrimitiveType>::Native,
726 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
727 tz: Tz,
728 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
729 subtract_month_day_nano::<Self>(timestamp, delta, tz)
730 }
731}
732
733impl TimestampNanosecondType {
734 pub fn add_year_months(
742 timestamp: <Self as ArrowPrimitiveType>::Native,
743 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
744 tz: Tz,
745 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
746 add_year_months::<Self>(timestamp, delta, tz)
747 }
748
749 pub fn add_day_time(
757 timestamp: <Self as ArrowPrimitiveType>::Native,
758 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
759 tz: Tz,
760 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
761 add_day_time::<Self>(timestamp, delta, tz)
762 }
763
764 pub fn add_month_day_nano(
772 timestamp: <Self as ArrowPrimitiveType>::Native,
773 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
774 tz: Tz,
775 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
776 add_month_day_nano::<Self>(timestamp, delta, tz)
777 }
778
779 pub fn subtract_year_months(
787 timestamp: <Self as ArrowPrimitiveType>::Native,
788 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
789 tz: Tz,
790 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
791 subtract_year_months::<Self>(timestamp, delta, tz)
792 }
793
794 pub fn subtract_day_time(
802 timestamp: <Self as ArrowPrimitiveType>::Native,
803 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
804 tz: Tz,
805 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
806 subtract_day_time::<Self>(timestamp, delta, tz)
807 }
808
809 pub fn subtract_month_day_nano(
817 timestamp: <Self as ArrowPrimitiveType>::Native,
818 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
819 tz: Tz,
820 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
821 subtract_month_day_nano::<Self>(timestamp, delta, tz)
822 }
823}
824
825impl IntervalYearMonthType {
826 #[inline]
833 pub fn make_value(
834 years: i32,
835 months: i32,
836 ) -> <IntervalYearMonthType as ArrowPrimitiveType>::Native {
837 years * 12 + months
838 }
839
840 #[inline]
848 pub fn to_months(i: <IntervalYearMonthType as ArrowPrimitiveType>::Native) -> i32 {
849 i
850 }
851}
852
853impl IntervalDayTimeType {
854 #[inline]
861 pub fn make_value(days: i32, milliseconds: i32) -> IntervalDayTime {
862 IntervalDayTime { days, milliseconds }
863 }
864
865 #[inline]
871 pub fn to_parts(i: IntervalDayTime) -> (i32, i32) {
872 (i.days, i.milliseconds)
873 }
874}
875
876impl IntervalMonthDayNanoType {
877 #[inline]
885 pub fn make_value(months: i32, days: i32, nanoseconds: i64) -> IntervalMonthDayNano {
886 IntervalMonthDayNano {
887 months,
888 days,
889 nanoseconds,
890 }
891 }
892
893 #[inline]
899 pub fn to_parts(i: IntervalMonthDayNano) -> (i32, i32, i64) {
900 (i.months, i.days, i.nanoseconds)
901 }
902}
903
904impl Date32Type {
905 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
911 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
912 epoch.add(Duration::try_days(i as i64).unwrap())
913 }
914
915 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
921 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
922 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
923 }
924
925 pub fn add_year_months(
932 date: <Date32Type as ArrowPrimitiveType>::Native,
933 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
934 ) -> <Date32Type as ArrowPrimitiveType>::Native {
935 let prior = Date32Type::to_naive_date(date);
936 let months = IntervalYearMonthType::to_months(delta);
937 let posterior = shift_months(prior, months);
938 Date32Type::from_naive_date(posterior)
939 }
940
941 pub fn add_day_time(
948 date: <Date32Type as ArrowPrimitiveType>::Native,
949 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
950 ) -> <Date32Type as ArrowPrimitiveType>::Native {
951 let (days, ms) = IntervalDayTimeType::to_parts(delta);
952 let res = Date32Type::to_naive_date(date);
953 let res = res.add(Duration::try_days(days as i64).unwrap());
954 let res = res.add(Duration::try_milliseconds(ms as i64).unwrap());
955 Date32Type::from_naive_date(res)
956 }
957
958 pub fn add_month_day_nano(
965 date: <Date32Type as ArrowPrimitiveType>::Native,
966 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
967 ) -> <Date32Type as ArrowPrimitiveType>::Native {
968 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
969 let res = Date32Type::to_naive_date(date);
970 let res = shift_months(res, months);
971 let res = res.add(Duration::try_days(days as i64).unwrap());
972 let res = res.add(Duration::nanoseconds(nanos));
973 Date32Type::from_naive_date(res)
974 }
975
976 pub fn subtract_year_months(
983 date: <Date32Type as ArrowPrimitiveType>::Native,
984 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
985 ) -> <Date32Type as ArrowPrimitiveType>::Native {
986 let prior = Date32Type::to_naive_date(date);
987 let months = IntervalYearMonthType::to_months(-delta);
988 let posterior = shift_months(prior, months);
989 Date32Type::from_naive_date(posterior)
990 }
991
992 pub fn subtract_day_time(
999 date: <Date32Type as ArrowPrimitiveType>::Native,
1000 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1001 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1002 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1003 let res = Date32Type::to_naive_date(date);
1004 let res = res.sub(Duration::try_days(days as i64).unwrap());
1005 let res = res.sub(Duration::try_milliseconds(ms as i64).unwrap());
1006 Date32Type::from_naive_date(res)
1007 }
1008
1009 pub fn subtract_month_day_nano(
1016 date: <Date32Type as ArrowPrimitiveType>::Native,
1017 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1018 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1019 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1020 let res = Date32Type::to_naive_date(date);
1021 let res = shift_months(res, -months);
1022 let res = res.sub(Duration::try_days(days as i64).unwrap());
1023 let res = res.sub(Duration::nanoseconds(nanos));
1024 Date32Type::from_naive_date(res)
1025 }
1026}
1027
1028impl Date64Type {
1029 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1035 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1036 epoch.add(Duration::try_milliseconds(i).unwrap())
1037 }
1038
1039 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1045 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1046 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1047 }
1048
1049 pub fn add_year_months(
1056 date: <Date64Type as ArrowPrimitiveType>::Native,
1057 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1058 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1059 let prior = Date64Type::to_naive_date(date);
1060 let months = IntervalYearMonthType::to_months(delta);
1061 let posterior = shift_months(prior, months);
1062 Date64Type::from_naive_date(posterior)
1063 }
1064
1065 pub fn add_day_time(
1072 date: <Date64Type as ArrowPrimitiveType>::Native,
1073 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1074 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1075 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1076 let res = Date64Type::to_naive_date(date);
1077 let res = res.add(Duration::try_days(days as i64).unwrap());
1078 let res = res.add(Duration::try_milliseconds(ms as i64).unwrap());
1079 Date64Type::from_naive_date(res)
1080 }
1081
1082 pub fn add_month_day_nano(
1089 date: <Date64Type as ArrowPrimitiveType>::Native,
1090 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1091 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1092 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1093 let res = Date64Type::to_naive_date(date);
1094 let res = shift_months(res, months);
1095 let res = res.add(Duration::try_days(days as i64).unwrap());
1096 let res = res.add(Duration::nanoseconds(nanos));
1097 Date64Type::from_naive_date(res)
1098 }
1099
1100 pub fn subtract_year_months(
1107 date: <Date64Type as ArrowPrimitiveType>::Native,
1108 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1109 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1110 let prior = Date64Type::to_naive_date(date);
1111 let months = IntervalYearMonthType::to_months(-delta);
1112 let posterior = shift_months(prior, months);
1113 Date64Type::from_naive_date(posterior)
1114 }
1115
1116 pub fn subtract_day_time(
1123 date: <Date64Type as ArrowPrimitiveType>::Native,
1124 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1125 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1126 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1127 let res = Date64Type::to_naive_date(date);
1128 let res = res.sub(Duration::try_days(days as i64).unwrap());
1129 let res = res.sub(Duration::try_milliseconds(ms as i64).unwrap());
1130 Date64Type::from_naive_date(res)
1131 }
1132
1133 pub fn subtract_month_day_nano(
1140 date: <Date64Type as ArrowPrimitiveType>::Native,
1141 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1142 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1143 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1144 let res = Date64Type::to_naive_date(date);
1145 let res = shift_months(res, -months);
1146 let res = res.sub(Duration::try_days(days as i64).unwrap());
1147 let res = res.sub(Duration::nanoseconds(nanos));
1148 Date64Type::from_naive_date(res)
1149 }
1150}
1151
1152mod decimal {
1156 use super::*;
1157
1158 pub trait DecimalTypeSealed {}
1159 impl DecimalTypeSealed for Decimal128Type {}
1160 impl DecimalTypeSealed for Decimal256Type {}
1161}
1162
1163pub trait DecimalType:
1173 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1174{
1175 const BYTE_LENGTH: usize;
1177 const MAX_PRECISION: u8;
1179 const MAX_SCALE: i8;
1181 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1183 const DEFAULT_TYPE: DataType;
1185
1186 const PREFIX: &'static str;
1188
1189 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1191
1192 fn validate_decimal_precision(value: Self::Native, precision: u8) -> Result<(), ArrowError>;
1194
1195 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1197}
1198
1199pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1207 precision: u8,
1208 scale: i8,
1209) -> Result<(), ArrowError> {
1210 if precision == 0 {
1211 return Err(ArrowError::InvalidArgumentError(format!(
1212 "precision cannot be 0, has to be between [1, {}]",
1213 T::MAX_PRECISION
1214 )));
1215 }
1216 if precision > T::MAX_PRECISION {
1217 return Err(ArrowError::InvalidArgumentError(format!(
1218 "precision {} is greater than max {}",
1219 precision,
1220 T::MAX_PRECISION
1221 )));
1222 }
1223 if scale > T::MAX_SCALE {
1224 return Err(ArrowError::InvalidArgumentError(format!(
1225 "scale {} is greater than max {}",
1226 scale,
1227 T::MAX_SCALE
1228 )));
1229 }
1230 if scale > 0 && scale as u8 > precision {
1231 return Err(ArrowError::InvalidArgumentError(format!(
1232 "scale {scale} is greater than precision {precision}"
1233 )));
1234 }
1235
1236 Ok(())
1237}
1238
1239#[derive(Debug)]
1241pub struct Decimal128Type {}
1242
1243impl DecimalType for Decimal128Type {
1244 const BYTE_LENGTH: usize = 16;
1245 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1246 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1247 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1248 const DEFAULT_TYPE: DataType =
1249 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1250 const PREFIX: &'static str = "Decimal128";
1251
1252 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1253 format_decimal_str(&value.to_string(), precision as usize, scale)
1254 }
1255
1256 fn validate_decimal_precision(num: i128, precision: u8) -> Result<(), ArrowError> {
1257 validate_decimal_precision(num, precision)
1258 }
1259
1260 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1261 is_validate_decimal_precision(value, precision)
1262 }
1263}
1264
1265impl ArrowPrimitiveType for Decimal128Type {
1266 type Native = i128;
1267
1268 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1269}
1270
1271impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1272
1273#[derive(Debug)]
1275pub struct Decimal256Type {}
1276
1277impl DecimalType for Decimal256Type {
1278 const BYTE_LENGTH: usize = 32;
1279 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1280 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1281 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1282 const DEFAULT_TYPE: DataType =
1283 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1284 const PREFIX: &'static str = "Decimal256";
1285
1286 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1287 format_decimal_str(&value.to_string(), precision as usize, scale)
1288 }
1289
1290 fn validate_decimal_precision(num: i256, precision: u8) -> Result<(), ArrowError> {
1291 validate_decimal256_precision(num, precision)
1292 }
1293
1294 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1295 is_validate_decimal256_precision(value, precision)
1296 }
1297}
1298
1299impl ArrowPrimitiveType for Decimal256Type {
1300 type Native = i256;
1301
1302 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1303}
1304
1305impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1306
1307fn format_decimal_str(value_str: &str, precision: usize, scale: i8) -> String {
1308 let (sign, rest) = match value_str.strip_prefix('-') {
1309 Some(stripped) => ("-", stripped),
1310 None => ("", value_str),
1311 };
1312 let bound = precision.min(rest.len()) + sign.len();
1313 let value_str = &value_str[0..bound];
1314
1315 if scale == 0 {
1316 value_str.to_string()
1317 } else if scale < 0 {
1318 let padding = value_str.len() + scale.unsigned_abs() as usize;
1319 format!("{value_str:0<padding$}")
1320 } else if rest.len() > scale as usize {
1321 let (whole, decimal) = value_str.split_at(value_str.len() - scale as usize);
1323 format!("{whole}.{decimal}")
1324 } else {
1325 format!("{}0.{:0>width$}", sign, rest, width = scale as usize)
1327 }
1328}
1329
1330pub(crate) mod bytes {
1334 use super::*;
1335
1336 pub trait ByteArrayTypeSealed {}
1337 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1338 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1339
1340 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1341 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1342
1343 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1347 }
1348
1349 impl ByteArrayNativeType for [u8] {
1350 #[inline]
1351 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1352 Some(b)
1353 }
1354
1355 #[inline]
1356 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1357 b
1358 }
1359 }
1360
1361 impl ByteArrayNativeType for str {
1362 #[inline]
1363 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1364 std::str::from_utf8(b).ok()
1365 }
1366
1367 #[inline]
1368 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1369 std::str::from_utf8_unchecked(b)
1370 }
1371 }
1372}
1373
1374pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1378 type Offset: OffsetSizeTrait;
1380 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1384
1385 const PREFIX: &'static str;
1387
1388 const DATA_TYPE: DataType;
1390
1391 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1393}
1394
1395pub struct GenericStringType<O: OffsetSizeTrait> {
1397 phantom: PhantomData<O>,
1398}
1399
1400impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1401 type Offset = O;
1402 type Native = str;
1403 const PREFIX: &'static str = "String";
1404
1405 const DATA_TYPE: DataType = if O::IS_LARGE {
1406 DataType::LargeUtf8
1407 } else {
1408 DataType::Utf8
1409 };
1410
1411 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1412 let validated = std::str::from_utf8(values).map_err(|e| {
1414 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1415 })?;
1416
1417 for offset in offsets.iter() {
1419 let o = offset.as_usize();
1420 if !validated.is_char_boundary(o) {
1421 if o < validated.len() {
1422 return Err(ArrowError::InvalidArgumentError(format!(
1423 "Split UTF-8 codepoint at offset {o}"
1424 )));
1425 }
1426 return Err(ArrowError::InvalidArgumentError(format!(
1427 "Offset of {o} exceeds length of values {}",
1428 validated.len()
1429 )));
1430 }
1431 }
1432 Ok(())
1433 }
1434}
1435
1436pub type Utf8Type = GenericStringType<i32>;
1438pub type LargeUtf8Type = GenericStringType<i64>;
1440
1441pub struct GenericBinaryType<O: OffsetSizeTrait> {
1443 phantom: PhantomData<O>,
1444}
1445
1446impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1447 type Offset = O;
1448 type Native = [u8];
1449 const PREFIX: &'static str = "Binary";
1450
1451 const DATA_TYPE: DataType = if O::IS_LARGE {
1452 DataType::LargeBinary
1453 } else {
1454 DataType::Binary
1455 };
1456
1457 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1458 let max_offset = offsets.last().unwrap().as_usize();
1460 if values.len() < max_offset {
1461 return Err(ArrowError::InvalidArgumentError(format!(
1462 "Maximum offset of {max_offset} is larger than values of length {}",
1463 values.len()
1464 )));
1465 }
1466 Ok(())
1467 }
1468}
1469
1470pub type BinaryType = GenericBinaryType<i32>;
1472pub type LargeBinaryType = GenericBinaryType<i64>;
1474
1475mod byte_view {
1476 use crate::types::{BinaryViewType, StringViewType};
1477
1478 pub trait Sealed: Send + Sync {}
1479 impl Sealed for StringViewType {}
1480 impl Sealed for BinaryViewType {}
1481}
1482
1483pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1485 const IS_UTF8: bool;
1487
1488 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1490 DataType::Utf8View
1491 } else {
1492 DataType::BinaryView
1493 };
1494
1495 const PREFIX: &'static str;
1497
1498 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1502
1503 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1505
1506 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1508}
1509
1510#[derive(PartialEq)]
1512pub struct StringViewType {}
1513
1514impl ByteViewType for StringViewType {
1515 const IS_UTF8: bool = true;
1516 const PREFIX: &'static str = "String";
1517
1518 type Native = str;
1519 type Owned = String;
1520
1521 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1522 validate_string_view(views, buffers)
1523 }
1524}
1525
1526#[derive(PartialEq)]
1528pub struct BinaryViewType {}
1529
1530impl ByteViewType for BinaryViewType {
1531 const IS_UTF8: bool = false;
1532 const PREFIX: &'static str = "Binary";
1533 type Native = [u8];
1534 type Owned = Vec<u8>;
1535
1536 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1537 validate_binary_view(views, buffers)
1538 }
1539}
1540
1541#[cfg(test)]
1542mod tests {
1543 use super::*;
1544 use arrow_data::{layout, BufferSpec};
1545
1546 #[test]
1547 fn month_day_nano_should_roundtrip() {
1548 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1549 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1550 }
1551
1552 #[test]
1553 fn month_day_nano_should_roundtrip_neg() {
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 day_time_should_roundtrip() {
1560 let value = IntervalDayTimeType::make_value(1, 2);
1561 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1562 }
1563
1564 #[test]
1565 fn day_time_should_roundtrip_neg() {
1566 let value = IntervalDayTimeType::make_value(-1, -2);
1567 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1568 }
1569
1570 #[test]
1571 fn year_month_should_roundtrip() {
1572 let value = IntervalYearMonthType::make_value(1, 2);
1573 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1574 }
1575
1576 #[test]
1577 fn year_month_should_roundtrip_neg() {
1578 let value = IntervalYearMonthType::make_value(-1, -2);
1579 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1580 }
1581
1582 fn test_layout<T: ArrowPrimitiveType>() {
1583 let layout = layout(&T::DATA_TYPE);
1584
1585 assert_eq!(layout.buffers.len(), 1);
1586
1587 let spec = &layout.buffers[0];
1588 assert_eq!(
1589 spec,
1590 &BufferSpec::FixedWidth {
1591 byte_width: std::mem::size_of::<T::Native>(),
1592 alignment: std::mem::align_of::<T::Native>(),
1593 }
1594 );
1595 }
1596
1597 #[test]
1598 fn test_layouts() {
1599 test_layout::<Int8Type>();
1600 test_layout::<Int16Type>();
1601 test_layout::<Int32Type>();
1602 test_layout::<Int64Type>();
1603 test_layout::<UInt8Type>();
1604 test_layout::<UInt16Type>();
1605 test_layout::<UInt32Type>();
1606 test_layout::<UInt64Type>();
1607 test_layout::<Float16Type>();
1608 test_layout::<Float32Type>();
1609 test_layout::<Float64Type>();
1610 test_layout::<Decimal128Type>();
1611 test_layout::<Decimal256Type>();
1612 test_layout::<TimestampNanosecondType>();
1613 test_layout::<TimestampMillisecondType>();
1614 test_layout::<TimestampMicrosecondType>();
1615 test_layout::<TimestampNanosecondType>();
1616 test_layout::<TimestampSecondType>();
1617 test_layout::<Date32Type>();
1618 test_layout::<Date64Type>();
1619 test_layout::<Time32SecondType>();
1620 test_layout::<Time32MillisecondType>();
1621 test_layout::<Time64MicrosecondType>();
1622 test_layout::<Time64NanosecondType>();
1623 test_layout::<IntervalMonthDayNanoType>();
1624 test_layout::<IntervalDayTimeType>();
1625 test_layout::<IntervalYearMonthType>();
1626 test_layout::<DurationNanosecondType>();
1627 test_layout::<DurationMicrosecondType>();
1628 test_layout::<DurationMillisecondType>();
1629 test_layout::<DurationSecondType>();
1630 }
1631}