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 #[deprecated]
1035 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1036 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1037 epoch.add(Duration::try_milliseconds(i).unwrap())
1038 }
1039
1040 pub fn to_naive_date_opt(i: <Date64Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
1051 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1052 Duration::try_milliseconds(i).and_then(|d| epoch.checked_add_signed(d))
1053 }
1054
1055 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1061 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1062 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1063 }
1064
1065 #[deprecated(
1072 since = "56.0.0",
1073 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
1074 )]
1075 pub fn add_year_months(
1076 date: <Date64Type as ArrowPrimitiveType>::Native,
1077 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1078 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1079 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
1080 panic!(
1081 "Date64Type::add_year_months overflowed for date: {}, delta: {}",
1082 date, delta
1083 )
1084 })
1085 }
1086
1087 pub fn add_year_months_opt(
1096 date: <Date64Type as ArrowPrimitiveType>::Native,
1097 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1098 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1099 let prior = Date64Type::to_naive_date_opt(date)?;
1100 let months = IntervalYearMonthType::to_months(delta);
1101 let posterior = shift_months(prior, months);
1102 Some(Date64Type::from_naive_date(posterior))
1103 }
1104
1105 #[deprecated(
1112 since = "56.0.0",
1113 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1114 )]
1115 pub fn add_day_time(
1116 date: <Date64Type as ArrowPrimitiveType>::Native,
1117 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1118 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1119 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1120 panic!(
1121 "Date64Type::add_day_time overflowed for date: {}, delta: {:?}",
1122 date, delta
1123 )
1124 })
1125 }
1126
1127 pub fn add_day_time_opt(
1136 date: <Date64Type as ArrowPrimitiveType>::Native,
1137 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1138 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1139 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1140 let res = Date64Type::to_naive_date_opt(date)?;
1141 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1142 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1143 Some(Date64Type::from_naive_date(res))
1144 }
1145
1146 #[deprecated(
1153 since = "56.0.0",
1154 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1155 )]
1156 pub fn add_month_day_nano(
1157 date: <Date64Type as ArrowPrimitiveType>::Native,
1158 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1159 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1160 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1161 panic!(
1162 "Date64Type::add_month_day_nano overflowed for date: {}, delta: {:?}",
1163 date, delta
1164 )
1165 })
1166 }
1167
1168 pub fn add_month_day_nano_opt(
1177 date: <Date64Type as ArrowPrimitiveType>::Native,
1178 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1179 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1180 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1181 let res = Date64Type::to_naive_date_opt(date)?;
1182 let res = shift_months(res, months);
1183 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1184 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1185 Some(Date64Type::from_naive_date(res))
1186 }
1187
1188 #[deprecated(
1195 since = "56.0.0",
1196 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1197 )]
1198 pub fn subtract_year_months(
1199 date: <Date64Type as ArrowPrimitiveType>::Native,
1200 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1201 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1202 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1203 panic!(
1204 "Date64Type::subtract_year_months overflowed for date: {}, delta: {}",
1205 date, delta
1206 )
1207 })
1208 }
1209
1210 pub fn subtract_year_months_opt(
1219 date: <Date64Type as ArrowPrimitiveType>::Native,
1220 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1221 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1222 let prior = Date64Type::to_naive_date_opt(date)?;
1223 let months = IntervalYearMonthType::to_months(-delta);
1224 let posterior = shift_months(prior, months);
1225 Some(Date64Type::from_naive_date(posterior))
1226 }
1227
1228 #[deprecated(
1235 since = "56.0.0",
1236 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1237 )]
1238 pub fn subtract_day_time(
1239 date: <Date64Type as ArrowPrimitiveType>::Native,
1240 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1241 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1242 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1243 panic!(
1244 "Date64Type::subtract_day_time overflowed for date: {}, delta: {:?}",
1245 date, delta
1246 )
1247 })
1248 }
1249
1250 pub fn subtract_day_time_opt(
1259 date: <Date64Type as ArrowPrimitiveType>::Native,
1260 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1261 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1262 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1263 let res = Date64Type::to_naive_date_opt(date)?;
1264 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1265 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1266 Some(Date64Type::from_naive_date(res))
1267 }
1268
1269 #[deprecated(
1276 since = "56.0.0",
1277 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1278 )]
1279 pub fn subtract_month_day_nano(
1280 date: <Date64Type as ArrowPrimitiveType>::Native,
1281 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1282 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1283 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1284 panic!(
1285 "Date64Type::subtract_month_day_nano overflowed for date: {}, delta: {:?}",
1286 date, delta
1287 )
1288 })
1289 }
1290
1291 pub fn subtract_month_day_nano_opt(
1300 date: <Date64Type as ArrowPrimitiveType>::Native,
1301 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1302 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1303 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1304 let res = Date64Type::to_naive_date_opt(date)?;
1305 let res = shift_months(res, -months);
1306 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1307 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1308 Some(Date64Type::from_naive_date(res))
1309 }
1310}
1311
1312mod decimal {
1316 use super::*;
1317
1318 pub trait DecimalTypeSealed {}
1319 impl DecimalTypeSealed for Decimal128Type {}
1320 impl DecimalTypeSealed for Decimal256Type {}
1321}
1322
1323pub trait DecimalType:
1333 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1334{
1335 const BYTE_LENGTH: usize;
1337 const MAX_PRECISION: u8;
1339 const MAX_SCALE: i8;
1341 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1343 const DEFAULT_TYPE: DataType;
1345
1346 const PREFIX: &'static str;
1348
1349 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1351
1352 fn validate_decimal_precision(value: Self::Native, precision: u8) -> Result<(), ArrowError>;
1354
1355 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1357}
1358
1359pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1367 precision: u8,
1368 scale: i8,
1369) -> Result<(), ArrowError> {
1370 if precision == 0 {
1371 return Err(ArrowError::InvalidArgumentError(format!(
1372 "precision cannot be 0, has to be between [1, {}]",
1373 T::MAX_PRECISION
1374 )));
1375 }
1376 if precision > T::MAX_PRECISION {
1377 return Err(ArrowError::InvalidArgumentError(format!(
1378 "precision {} is greater than max {}",
1379 precision,
1380 T::MAX_PRECISION
1381 )));
1382 }
1383 if scale > T::MAX_SCALE {
1384 return Err(ArrowError::InvalidArgumentError(format!(
1385 "scale {} is greater than max {}",
1386 scale,
1387 T::MAX_SCALE
1388 )));
1389 }
1390 if scale > 0 && scale as u8 > precision {
1391 return Err(ArrowError::InvalidArgumentError(format!(
1392 "scale {scale} is greater than precision {precision}"
1393 )));
1394 }
1395
1396 Ok(())
1397}
1398
1399#[derive(Debug)]
1401pub struct Decimal128Type {}
1402
1403impl DecimalType for Decimal128Type {
1404 const BYTE_LENGTH: usize = 16;
1405 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1406 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1407 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1408 const DEFAULT_TYPE: DataType =
1409 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1410 const PREFIX: &'static str = "Decimal128";
1411
1412 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1413 format_decimal_str(&value.to_string(), precision as usize, scale)
1414 }
1415
1416 fn validate_decimal_precision(num: i128, precision: u8) -> Result<(), ArrowError> {
1417 validate_decimal_precision(num, precision)
1418 }
1419
1420 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1421 is_validate_decimal_precision(value, precision)
1422 }
1423}
1424
1425impl ArrowPrimitiveType for Decimal128Type {
1426 type Native = i128;
1427
1428 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1429}
1430
1431impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1432
1433#[derive(Debug)]
1435pub struct Decimal256Type {}
1436
1437impl DecimalType for Decimal256Type {
1438 const BYTE_LENGTH: usize = 32;
1439 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1440 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1441 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1442 const DEFAULT_TYPE: DataType =
1443 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1444 const PREFIX: &'static str = "Decimal256";
1445
1446 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1447 format_decimal_str(&value.to_string(), precision as usize, scale)
1448 }
1449
1450 fn validate_decimal_precision(num: i256, precision: u8) -> Result<(), ArrowError> {
1451 validate_decimal256_precision(num, precision)
1452 }
1453
1454 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1455 is_validate_decimal256_precision(value, precision)
1456 }
1457}
1458
1459impl ArrowPrimitiveType for Decimal256Type {
1460 type Native = i256;
1461
1462 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1463}
1464
1465impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1466
1467fn format_decimal_str(value_str: &str, precision: usize, scale: i8) -> String {
1468 let (sign, rest) = match value_str.strip_prefix('-') {
1469 Some(stripped) => ("-", stripped),
1470 None => ("", value_str),
1471 };
1472 let bound = precision.min(rest.len()) + sign.len();
1473 let value_str = &value_str[0..bound];
1474
1475 if scale == 0 {
1476 value_str.to_string()
1477 } else if scale < 0 {
1478 let padding = value_str.len() + scale.unsigned_abs() as usize;
1479 format!("{value_str:0<padding$}")
1480 } else if rest.len() > scale as usize {
1481 let (whole, decimal) = value_str.split_at(value_str.len() - scale as usize);
1483 format!("{whole}.{decimal}")
1484 } else {
1485 format!("{}0.{:0>width$}", sign, rest, width = scale as usize)
1487 }
1488}
1489
1490pub(crate) mod bytes {
1494 use super::*;
1495
1496 pub trait ByteArrayTypeSealed {}
1497 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1498 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1499
1500 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1501 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1502
1503 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1507 }
1508
1509 impl ByteArrayNativeType for [u8] {
1510 #[inline]
1511 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1512 Some(b)
1513 }
1514
1515 #[inline]
1516 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1517 b
1518 }
1519 }
1520
1521 impl ByteArrayNativeType for str {
1522 #[inline]
1523 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1524 std::str::from_utf8(b).ok()
1525 }
1526
1527 #[inline]
1528 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1529 std::str::from_utf8_unchecked(b)
1530 }
1531 }
1532}
1533
1534pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1538 type Offset: OffsetSizeTrait;
1540 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1544
1545 const PREFIX: &'static str;
1547
1548 const DATA_TYPE: DataType;
1550
1551 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1553}
1554
1555pub struct GenericStringType<O: OffsetSizeTrait> {
1557 phantom: PhantomData<O>,
1558}
1559
1560impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1561 type Offset = O;
1562 type Native = str;
1563 const PREFIX: &'static str = "String";
1564
1565 const DATA_TYPE: DataType = if O::IS_LARGE {
1566 DataType::LargeUtf8
1567 } else {
1568 DataType::Utf8
1569 };
1570
1571 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1572 let validated = std::str::from_utf8(values).map_err(|e| {
1574 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1575 })?;
1576
1577 for offset in offsets.iter() {
1579 let o = offset.as_usize();
1580 if !validated.is_char_boundary(o) {
1581 if o < validated.len() {
1582 return Err(ArrowError::InvalidArgumentError(format!(
1583 "Split UTF-8 codepoint at offset {o}"
1584 )));
1585 }
1586 return Err(ArrowError::InvalidArgumentError(format!(
1587 "Offset of {o} exceeds length of values {}",
1588 validated.len()
1589 )));
1590 }
1591 }
1592 Ok(())
1593 }
1594}
1595
1596pub type Utf8Type = GenericStringType<i32>;
1598pub type LargeUtf8Type = GenericStringType<i64>;
1600
1601pub struct GenericBinaryType<O: OffsetSizeTrait> {
1603 phantom: PhantomData<O>,
1604}
1605
1606impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1607 type Offset = O;
1608 type Native = [u8];
1609 const PREFIX: &'static str = "Binary";
1610
1611 const DATA_TYPE: DataType = if O::IS_LARGE {
1612 DataType::LargeBinary
1613 } else {
1614 DataType::Binary
1615 };
1616
1617 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1618 let max_offset = offsets.last().unwrap().as_usize();
1620 if values.len() < max_offset {
1621 return Err(ArrowError::InvalidArgumentError(format!(
1622 "Maximum offset of {max_offset} is larger than values of length {}",
1623 values.len()
1624 )));
1625 }
1626 Ok(())
1627 }
1628}
1629
1630pub type BinaryType = GenericBinaryType<i32>;
1632pub type LargeBinaryType = GenericBinaryType<i64>;
1634
1635mod byte_view {
1636 use crate::types::{BinaryViewType, StringViewType};
1637
1638 pub trait Sealed: Send + Sync {}
1639 impl Sealed for StringViewType {}
1640 impl Sealed for BinaryViewType {}
1641}
1642
1643pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1645 const IS_UTF8: bool;
1647
1648 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1650 DataType::Utf8View
1651 } else {
1652 DataType::BinaryView
1653 };
1654
1655 const PREFIX: &'static str;
1657
1658 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1662
1663 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1665
1666 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1668}
1669
1670#[derive(PartialEq)]
1672pub struct StringViewType {}
1673
1674impl ByteViewType for StringViewType {
1675 const IS_UTF8: bool = true;
1676 const PREFIX: &'static str = "String";
1677
1678 type Native = str;
1679 type Owned = String;
1680
1681 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1682 validate_string_view(views, buffers)
1683 }
1684}
1685
1686#[derive(PartialEq)]
1688pub struct BinaryViewType {}
1689
1690impl ByteViewType for BinaryViewType {
1691 const IS_UTF8: bool = false;
1692 const PREFIX: &'static str = "Binary";
1693 type Native = [u8];
1694 type Owned = Vec<u8>;
1695
1696 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1697 validate_binary_view(views, buffers)
1698 }
1699}
1700
1701#[cfg(test)]
1702mod tests {
1703 use super::*;
1704 use arrow_data::{layout, BufferSpec};
1705
1706 #[test]
1707 fn month_day_nano_should_roundtrip() {
1708 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1709 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1710 }
1711
1712 #[test]
1713 fn month_day_nano_should_roundtrip_neg() {
1714 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1715 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1716 }
1717
1718 #[test]
1719 fn day_time_should_roundtrip() {
1720 let value = IntervalDayTimeType::make_value(1, 2);
1721 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1722 }
1723
1724 #[test]
1725 fn day_time_should_roundtrip_neg() {
1726 let value = IntervalDayTimeType::make_value(-1, -2);
1727 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1728 }
1729
1730 #[test]
1731 fn year_month_should_roundtrip() {
1732 let value = IntervalYearMonthType::make_value(1, 2);
1733 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1734 }
1735
1736 #[test]
1737 fn year_month_should_roundtrip_neg() {
1738 let value = IntervalYearMonthType::make_value(-1, -2);
1739 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1740 }
1741
1742 fn test_layout<T: ArrowPrimitiveType>() {
1743 let layout = layout(&T::DATA_TYPE);
1744
1745 assert_eq!(layout.buffers.len(), 1);
1746
1747 let spec = &layout.buffers[0];
1748 assert_eq!(
1749 spec,
1750 &BufferSpec::FixedWidth {
1751 byte_width: std::mem::size_of::<T::Native>(),
1752 alignment: std::mem::align_of::<T::Native>(),
1753 }
1754 );
1755 }
1756
1757 #[test]
1758 fn test_layouts() {
1759 test_layout::<Int8Type>();
1760 test_layout::<Int16Type>();
1761 test_layout::<Int32Type>();
1762 test_layout::<Int64Type>();
1763 test_layout::<UInt8Type>();
1764 test_layout::<UInt16Type>();
1765 test_layout::<UInt32Type>();
1766 test_layout::<UInt64Type>();
1767 test_layout::<Float16Type>();
1768 test_layout::<Float32Type>();
1769 test_layout::<Float64Type>();
1770 test_layout::<Decimal128Type>();
1771 test_layout::<Decimal256Type>();
1772 test_layout::<TimestampNanosecondType>();
1773 test_layout::<TimestampMillisecondType>();
1774 test_layout::<TimestampMicrosecondType>();
1775 test_layout::<TimestampNanosecondType>();
1776 test_layout::<TimestampSecondType>();
1777 test_layout::<Date32Type>();
1778 test_layout::<Date64Type>();
1779 test_layout::<Time32SecondType>();
1780 test_layout::<Time32MillisecondType>();
1781 test_layout::<Time64MicrosecondType>();
1782 test_layout::<Time64NanosecondType>();
1783 test_layout::<IntervalMonthDayNanoType>();
1784 test_layout::<IntervalDayTimeType>();
1785 test_layout::<IntervalYearMonthType>();
1786 test_layout::<DurationNanosecondType>();
1787 test_layout::<DurationMicrosecondType>();
1788 test_layout::<DurationMillisecondType>();
1789 test_layout::<DurationSecondType>();
1790 }
1791}