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::{Buffer, OffsetBuffer, i256};
27use arrow_data::decimal::{
28 format_decimal_str, is_validate_decimal_precision, is_validate_decimal32_precision,
29 is_validate_decimal64_precision, is_validate_decimal256_precision, validate_decimal_precision,
30 validate_decimal32_precision, validate_decimal64_precision, validate_decimal256_precision,
31};
32use arrow_data::{validate_binary_view, validate_string_view};
33use arrow_schema::{
34 ArrowError, DECIMAL_DEFAULT_SCALE, DECIMAL32_DEFAULT_SCALE, DECIMAL32_MAX_PRECISION,
35 DECIMAL32_MAX_SCALE, DECIMAL64_DEFAULT_SCALE, DECIMAL64_MAX_PRECISION, DECIMAL64_MAX_SCALE,
36 DECIMAL128_MAX_PRECISION, DECIMAL128_MAX_SCALE, DECIMAL256_MAX_PRECISION, DECIMAL256_MAX_SCALE,
37 DataType, IntervalUnit, TimeUnit,
38};
39use chrono::{Duration, NaiveDate, NaiveDateTime};
40use half::f16;
41use std::fmt::Debug;
42use std::marker::PhantomData;
43use std::ops::{Add, Sub};
44
45pub use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
47
48#[derive(Debug)]
52pub struct BooleanType {}
53
54impl BooleanType {
55 pub const DATA_TYPE: DataType = DataType::Boolean;
57}
58
59pub trait ArrowPrimitiveType: primitive::PrimitiveTypeSealed + 'static {
68 type Native: ArrowNativeTypeOp;
70
71 const DATA_TYPE: DataType;
73
74 fn default_value() -> Self::Native {
78 Default::default()
79 }
80}
81
82mod primitive {
83 pub trait PrimitiveTypeSealed {}
84}
85
86macro_rules! make_type {
87 ($name:ident, $native_ty:ty, $data_ty:expr, $doc_string: literal) => {
88 #[derive(Debug)]
89 #[doc = $doc_string]
90 pub struct $name {}
91
92 impl ArrowPrimitiveType for $name {
93 type Native = $native_ty;
94 const DATA_TYPE: DataType = $data_ty;
95 }
96
97 impl primitive::PrimitiveTypeSealed for $name {}
98 };
99}
100
101make_type!(Int8Type, i8, DataType::Int8, "A signed 8-bit integer type.");
102make_type!(
103 Int16Type,
104 i16,
105 DataType::Int16,
106 "Signed 16-bit integer type."
107);
108make_type!(
109 Int32Type,
110 i32,
111 DataType::Int32,
112 "Signed 32-bit integer type."
113);
114make_type!(
115 Int64Type,
116 i64,
117 DataType::Int64,
118 "Signed 64-bit integer type."
119);
120make_type!(
121 UInt8Type,
122 u8,
123 DataType::UInt8,
124 "Unsigned 8-bit integer type."
125);
126make_type!(
127 UInt16Type,
128 u16,
129 DataType::UInt16,
130 "Unsigned 16-bit integer type."
131);
132make_type!(
133 UInt32Type,
134 u32,
135 DataType::UInt32,
136 "Unsigned 32-bit integer type."
137);
138make_type!(
139 UInt64Type,
140 u64,
141 DataType::UInt64,
142 "Unsigned 64-bit integer type."
143);
144make_type!(
145 Float16Type,
146 f16,
147 DataType::Float16,
148 "16-bit floating point number type."
149);
150make_type!(
151 Float32Type,
152 f32,
153 DataType::Float32,
154 "32-bit floating point number type."
155);
156make_type!(
157 Float64Type,
158 f64,
159 DataType::Float64,
160 "64-bit floating point number type."
161);
162make_type!(
163 TimestampSecondType,
164 i64,
165 DataType::Timestamp(TimeUnit::Second, None),
166 "Timestamp second type with an optional timezone."
167);
168make_type!(
169 TimestampMillisecondType,
170 i64,
171 DataType::Timestamp(TimeUnit::Millisecond, None),
172 "Timestamp millisecond type with an optional timezone."
173);
174make_type!(
175 TimestampMicrosecondType,
176 i64,
177 DataType::Timestamp(TimeUnit::Microsecond, None),
178 "Timestamp microsecond type with an optional timezone."
179);
180make_type!(
181 TimestampNanosecondType,
182 i64,
183 DataType::Timestamp(TimeUnit::Nanosecond, None),
184 "Timestamp nanosecond type with an optional timezone."
185);
186make_type!(
187 Date32Type,
188 i32,
189 DataType::Date32,
190 "32-bit date type: the elapsed time since UNIX epoch in days (32 bits)."
191);
192make_type!(
193 Date64Type,
194 i64,
195 DataType::Date64,
196 "64-bit date type: the elapsed time since UNIX epoch in milliseconds (64 bits). \
197 Values must be divisible by `86_400_000`. \
198 See [`DataType::Date64`] for more details."
199);
200make_type!(
201 Time32SecondType,
202 i32,
203 DataType::Time32(TimeUnit::Second),
204 "32-bit time type: the elapsed time since midnight in seconds."
205);
206make_type!(
207 Time32MillisecondType,
208 i32,
209 DataType::Time32(TimeUnit::Millisecond),
210 "32-bit time type: the elapsed time since midnight in milliseconds."
211);
212make_type!(
213 Time64MicrosecondType,
214 i64,
215 DataType::Time64(TimeUnit::Microsecond),
216 "64-bit time type: the elapsed time since midnight in microseconds."
217);
218make_type!(
219 Time64NanosecondType,
220 i64,
221 DataType::Time64(TimeUnit::Nanosecond),
222 "64-bit time type: the elapsed time since midnight in nanoseconds."
223);
224make_type!(
225 IntervalYearMonthType,
226 i32,
227 DataType::Interval(IntervalUnit::YearMonth),
228 "32-bit “calendar” interval type: the number of whole months."
229);
230make_type!(
231 IntervalDayTimeType,
232 IntervalDayTime,
233 DataType::Interval(IntervalUnit::DayTime),
234 "“Calendar” interval type: days and milliseconds. See [`IntervalDayTime`] for more details."
235);
236make_type!(
237 IntervalMonthDayNanoType,
238 IntervalMonthDayNano,
239 DataType::Interval(IntervalUnit::MonthDayNano),
240 r"“Calendar” interval type: months, days, and nanoseconds. See [`IntervalMonthDayNano`] for more details."
241);
242make_type!(
243 DurationSecondType,
244 i64,
245 DataType::Duration(TimeUnit::Second),
246 "Elapsed time type: seconds."
247);
248make_type!(
249 DurationMillisecondType,
250 i64,
251 DataType::Duration(TimeUnit::Millisecond),
252 "Elapsed time type: milliseconds."
253);
254make_type!(
255 DurationMicrosecondType,
256 i64,
257 DataType::Duration(TimeUnit::Microsecond),
258 "Elapsed time type: microseconds."
259);
260make_type!(
261 DurationNanosecondType,
262 i64,
263 DataType::Duration(TimeUnit::Nanosecond),
264 "Elapsed time type: nanoseconds."
265);
266
267pub trait ArrowDictionaryKeyType: ArrowPrimitiveType {}
270
271impl ArrowDictionaryKeyType for Int8Type {}
272
273impl ArrowDictionaryKeyType for Int16Type {}
274
275impl ArrowDictionaryKeyType for Int32Type {}
276
277impl ArrowDictionaryKeyType for Int64Type {}
278
279impl ArrowDictionaryKeyType for UInt8Type {}
280
281impl ArrowDictionaryKeyType for UInt16Type {}
282
283impl ArrowDictionaryKeyType for UInt32Type {}
284
285impl ArrowDictionaryKeyType for UInt64Type {}
286
287pub trait RunEndIndexType: ArrowPrimitiveType {}
291
292impl RunEndIndexType for Int16Type {}
293
294impl RunEndIndexType for Int32Type {}
295
296impl RunEndIndexType for Int64Type {}
297
298pub trait ArrowTemporalType: ArrowPrimitiveType {}
300
301impl ArrowTemporalType for TimestampSecondType {}
302impl ArrowTemporalType for TimestampMillisecondType {}
303impl ArrowTemporalType for TimestampMicrosecondType {}
304impl ArrowTemporalType for TimestampNanosecondType {}
305impl ArrowTemporalType for Date32Type {}
306impl ArrowTemporalType for Date64Type {}
307impl ArrowTemporalType for Time32SecondType {}
308impl ArrowTemporalType for Time32MillisecondType {}
309impl ArrowTemporalType for Time64MicrosecondType {}
310impl ArrowTemporalType for Time64NanosecondType {}
311impl ArrowTemporalType for DurationSecondType {}
315impl ArrowTemporalType for DurationMillisecondType {}
316impl ArrowTemporalType for DurationMicrosecondType {}
317impl ArrowTemporalType for DurationNanosecondType {}
318
319pub trait ArrowTimestampType: ArrowTemporalType<Native = i64> {
321 const UNIT: TimeUnit;
323
324 fn make_value(naive: NaiveDateTime) -> Option<i64>;
328}
329
330impl ArrowTimestampType for TimestampSecondType {
331 const UNIT: TimeUnit = TimeUnit::Second;
332
333 fn make_value(naive: NaiveDateTime) -> Option<i64> {
334 Some(naive.and_utc().timestamp())
335 }
336}
337impl ArrowTimestampType for TimestampMillisecondType {
338 const UNIT: TimeUnit = TimeUnit::Millisecond;
339
340 fn make_value(naive: NaiveDateTime) -> Option<i64> {
341 let utc = naive.and_utc();
342 let millis = utc.timestamp().checked_mul(1_000)?;
343 millis.checked_add(utc.timestamp_subsec_millis() as i64)
344 }
345}
346impl ArrowTimestampType for TimestampMicrosecondType {
347 const UNIT: TimeUnit = TimeUnit::Microsecond;
348
349 fn make_value(naive: NaiveDateTime) -> Option<i64> {
350 let utc = naive.and_utc();
351 let micros = utc.timestamp().checked_mul(1_000_000)?;
352 micros.checked_add(utc.timestamp_subsec_micros() as i64)
353 }
354}
355impl ArrowTimestampType for TimestampNanosecondType {
356 const UNIT: TimeUnit = TimeUnit::Nanosecond;
357
358 fn make_value(naive: NaiveDateTime) -> Option<i64> {
359 let utc = naive.and_utc();
360 let nanos = utc.timestamp().checked_mul(1_000_000_000)?;
361 nanos.checked_add(utc.timestamp_subsec_nanos() as i64)
362 }
363}
364
365fn add_year_months<T: ArrowTimestampType>(
366 timestamp: <T as ArrowPrimitiveType>::Native,
367 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
368 tz: Tz,
369) -> Option<<T as ArrowPrimitiveType>::Native> {
370 let months = IntervalYearMonthType::to_months(delta);
371 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
372 let res = add_months_datetime(res, months)?;
373 let res = res.naive_utc();
374 T::make_value(res)
375}
376
377fn add_day_time<T: ArrowTimestampType>(
378 timestamp: <T as ArrowPrimitiveType>::Native,
379 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
380 tz: Tz,
381) -> Option<<T as ArrowPrimitiveType>::Native> {
382 let (days, ms) = IntervalDayTimeType::to_parts(delta);
383 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
384 let res = add_days_datetime(res, days)?;
385 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
386 let res = res.naive_utc();
387 T::make_value(res)
388}
389
390fn add_month_day_nano<T: ArrowTimestampType>(
391 timestamp: <T as ArrowPrimitiveType>::Native,
392 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
393 tz: Tz,
394) -> Option<<T as ArrowPrimitiveType>::Native> {
395 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
396 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
397 let res = add_months_datetime(res, months)?;
398 let res = add_days_datetime(res, days)?;
399 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
400 let res = res.naive_utc();
401 T::make_value(res)
402}
403
404fn subtract_year_months<T: ArrowTimestampType>(
405 timestamp: <T as ArrowPrimitiveType>::Native,
406 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
407 tz: Tz,
408) -> Option<<T as ArrowPrimitiveType>::Native> {
409 let months = IntervalYearMonthType::to_months(delta);
410 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
411 let res = sub_months_datetime(res, months)?;
412 let res = res.naive_utc();
413 T::make_value(res)
414}
415
416fn subtract_day_time<T: ArrowTimestampType>(
417 timestamp: <T as ArrowPrimitiveType>::Native,
418 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
419 tz: Tz,
420) -> Option<<T as ArrowPrimitiveType>::Native> {
421 let (days, ms) = IntervalDayTimeType::to_parts(delta);
422 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
423 let res = sub_days_datetime(res, days)?;
424 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
425 let res = res.naive_utc();
426 T::make_value(res)
427}
428
429fn subtract_month_day_nano<T: ArrowTimestampType>(
430 timestamp: <T as ArrowPrimitiveType>::Native,
431 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
432 tz: Tz,
433) -> Option<<T as ArrowPrimitiveType>::Native> {
434 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
435 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
436 let res = sub_months_datetime(res, months)?;
437 let res = sub_days_datetime(res, days)?;
438 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
439 let res = res.naive_utc();
440 T::make_value(res)
441}
442
443impl TimestampSecondType {
444 pub fn add_year_months(
454 timestamp: <Self as ArrowPrimitiveType>::Native,
455 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
456 tz: Tz,
457 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
458 add_year_months::<Self>(timestamp, delta, tz)
459 }
460
461 pub fn add_day_time(
471 timestamp: <Self as ArrowPrimitiveType>::Native,
472 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
473 tz: Tz,
474 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
475 add_day_time::<Self>(timestamp, delta, tz)
476 }
477
478 pub fn add_month_day_nano(
487 timestamp: <Self as ArrowPrimitiveType>::Native,
488 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
489 tz: Tz,
490 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
491 add_month_day_nano::<Self>(timestamp, delta, tz)
492 }
493
494 pub fn subtract_year_months(
504 timestamp: <Self as ArrowPrimitiveType>::Native,
505 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
506 tz: Tz,
507 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
508 subtract_year_months::<Self>(timestamp, delta, tz)
509 }
510
511 pub fn subtract_day_time(
521 timestamp: <Self as ArrowPrimitiveType>::Native,
522 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
523 tz: Tz,
524 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
525 subtract_day_time::<Self>(timestamp, delta, tz)
526 }
527
528 pub fn subtract_month_day_nano(
538 timestamp: <Self as ArrowPrimitiveType>::Native,
539 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
540 tz: Tz,
541 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
542 subtract_month_day_nano::<Self>(timestamp, delta, tz)
543 }
544}
545
546impl TimestampMicrosecondType {
547 pub fn add_year_months(
555 timestamp: <Self as ArrowPrimitiveType>::Native,
556 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
557 tz: Tz,
558 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
559 add_year_months::<Self>(timestamp, delta, tz)
560 }
561
562 pub fn add_day_time(
570 timestamp: <Self as ArrowPrimitiveType>::Native,
571 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
572 tz: Tz,
573 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
574 add_day_time::<Self>(timestamp, delta, tz)
575 }
576
577 pub fn add_month_day_nano(
585 timestamp: <Self as ArrowPrimitiveType>::Native,
586 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
587 tz: Tz,
588 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
589 add_month_day_nano::<Self>(timestamp, delta, tz)
590 }
591
592 pub fn subtract_year_months(
600 timestamp: <Self as ArrowPrimitiveType>::Native,
601 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
602 tz: Tz,
603 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
604 subtract_year_months::<Self>(timestamp, delta, tz)
605 }
606
607 pub fn subtract_day_time(
615 timestamp: <Self as ArrowPrimitiveType>::Native,
616 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
617 tz: Tz,
618 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
619 subtract_day_time::<Self>(timestamp, delta, tz)
620 }
621
622 pub fn subtract_month_day_nano(
630 timestamp: <Self as ArrowPrimitiveType>::Native,
631 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
632 tz: Tz,
633 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
634 subtract_month_day_nano::<Self>(timestamp, delta, tz)
635 }
636}
637
638impl TimestampMillisecondType {
639 pub fn add_year_months(
647 timestamp: <Self as ArrowPrimitiveType>::Native,
648 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
649 tz: Tz,
650 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
651 add_year_months::<Self>(timestamp, delta, tz)
652 }
653
654 pub fn add_day_time(
662 timestamp: <Self as ArrowPrimitiveType>::Native,
663 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
664 tz: Tz,
665 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
666 add_day_time::<Self>(timestamp, delta, tz)
667 }
668
669 pub fn add_month_day_nano(
677 timestamp: <Self as ArrowPrimitiveType>::Native,
678 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
679 tz: Tz,
680 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
681 add_month_day_nano::<Self>(timestamp, delta, tz)
682 }
683
684 pub fn subtract_year_months(
692 timestamp: <Self as ArrowPrimitiveType>::Native,
693 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
694 tz: Tz,
695 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
696 subtract_year_months::<Self>(timestamp, delta, tz)
697 }
698
699 pub fn subtract_day_time(
707 timestamp: <Self as ArrowPrimitiveType>::Native,
708 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
709 tz: Tz,
710 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
711 subtract_day_time::<Self>(timestamp, delta, tz)
712 }
713
714 pub fn subtract_month_day_nano(
722 timestamp: <Self as ArrowPrimitiveType>::Native,
723 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
724 tz: Tz,
725 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
726 subtract_month_day_nano::<Self>(timestamp, delta, tz)
727 }
728}
729
730impl TimestampNanosecondType {
731 pub fn add_year_months(
739 timestamp: <Self as ArrowPrimitiveType>::Native,
740 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
741 tz: Tz,
742 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
743 add_year_months::<Self>(timestamp, delta, tz)
744 }
745
746 pub fn add_day_time(
754 timestamp: <Self as ArrowPrimitiveType>::Native,
755 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
756 tz: Tz,
757 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
758 add_day_time::<Self>(timestamp, delta, tz)
759 }
760
761 pub fn add_month_day_nano(
769 timestamp: <Self as ArrowPrimitiveType>::Native,
770 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
771 tz: Tz,
772 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
773 add_month_day_nano::<Self>(timestamp, delta, tz)
774 }
775
776 pub fn subtract_year_months(
784 timestamp: <Self as ArrowPrimitiveType>::Native,
785 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
786 tz: Tz,
787 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
788 subtract_year_months::<Self>(timestamp, delta, tz)
789 }
790
791 pub fn subtract_day_time(
799 timestamp: <Self as ArrowPrimitiveType>::Native,
800 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
801 tz: Tz,
802 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
803 subtract_day_time::<Self>(timestamp, delta, tz)
804 }
805
806 pub fn subtract_month_day_nano(
814 timestamp: <Self as ArrowPrimitiveType>::Native,
815 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
816 tz: Tz,
817 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
818 subtract_month_day_nano::<Self>(timestamp, delta, tz)
819 }
820}
821
822impl IntervalYearMonthType {
823 #[inline]
830 pub fn make_value(
831 years: i32,
832 months: i32,
833 ) -> <IntervalYearMonthType as ArrowPrimitiveType>::Native {
834 years * 12 + months
835 }
836
837 #[inline]
845 pub fn to_months(i: <IntervalYearMonthType as ArrowPrimitiveType>::Native) -> i32 {
846 i
847 }
848}
849
850impl IntervalDayTimeType {
851 #[inline]
858 pub fn make_value(days: i32, milliseconds: i32) -> IntervalDayTime {
859 IntervalDayTime { days, milliseconds }
860 }
861
862 #[inline]
868 pub fn to_parts(i: IntervalDayTime) -> (i32, i32) {
869 (i.days, i.milliseconds)
870 }
871}
872
873impl IntervalMonthDayNanoType {
874 #[inline]
882 pub fn make_value(months: i32, days: i32, nanoseconds: i64) -> IntervalMonthDayNano {
883 IntervalMonthDayNano {
884 months,
885 days,
886 nanoseconds,
887 }
888 }
889
890 #[inline]
896 pub fn to_parts(i: IntervalMonthDayNano) -> (i32, i32, i64) {
897 (i.months, i.days, i.nanoseconds)
898 }
899}
900
901impl Date32Type {
902 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
908 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
909 epoch.add(Duration::try_days(i as i64).unwrap())
910 }
911
912 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
918 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
919 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
920 }
921
922 pub fn add_year_months(
929 date: <Date32Type as ArrowPrimitiveType>::Native,
930 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
931 ) -> <Date32Type as ArrowPrimitiveType>::Native {
932 let prior = Date32Type::to_naive_date(date);
933 let months = IntervalYearMonthType::to_months(delta);
934 let posterior = shift_months(prior, months);
935 Date32Type::from_naive_date(posterior)
936 }
937
938 pub fn add_day_time(
945 date: <Date32Type as ArrowPrimitiveType>::Native,
946 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
947 ) -> <Date32Type as ArrowPrimitiveType>::Native {
948 let (days, ms) = IntervalDayTimeType::to_parts(delta);
949 let res = Date32Type::to_naive_date(date);
950 let res = res.add(Duration::try_days(days as i64).unwrap());
951 let res = res.add(Duration::try_milliseconds(ms as i64).unwrap());
952 Date32Type::from_naive_date(res)
953 }
954
955 pub fn add_month_day_nano(
962 date: <Date32Type as ArrowPrimitiveType>::Native,
963 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
964 ) -> <Date32Type as ArrowPrimitiveType>::Native {
965 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
966 let res = Date32Type::to_naive_date(date);
967 let res = shift_months(res, months);
968 let res = res.add(Duration::try_days(days as i64).unwrap());
969 let res = res.add(Duration::nanoseconds(nanos));
970 Date32Type::from_naive_date(res)
971 }
972
973 pub fn subtract_year_months(
980 date: <Date32Type as ArrowPrimitiveType>::Native,
981 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
982 ) -> <Date32Type as ArrowPrimitiveType>::Native {
983 let prior = Date32Type::to_naive_date(date);
984 let months = IntervalYearMonthType::to_months(-delta);
985 let posterior = shift_months(prior, months);
986 Date32Type::from_naive_date(posterior)
987 }
988
989 pub fn subtract_day_time(
996 date: <Date32Type as ArrowPrimitiveType>::Native,
997 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
998 ) -> <Date32Type as ArrowPrimitiveType>::Native {
999 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1000 let res = Date32Type::to_naive_date(date);
1001 let res = res.sub(Duration::try_days(days as i64).unwrap());
1002 let res = res.sub(Duration::try_milliseconds(ms as i64).unwrap());
1003 Date32Type::from_naive_date(res)
1004 }
1005
1006 pub fn subtract_month_day_nano(
1013 date: <Date32Type as ArrowPrimitiveType>::Native,
1014 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1015 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1016 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1017 let res = Date32Type::to_naive_date(date);
1018 let res = shift_months(res, -months);
1019 let res = res.sub(Duration::try_days(days as i64).unwrap());
1020 let res = res.sub(Duration::nanoseconds(nanos));
1021 Date32Type::from_naive_date(res)
1022 }
1023}
1024
1025impl Date64Type {
1026 #[deprecated(since = "56.0.0", note = "Use to_naive_date_opt instead.")]
1032 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1033 Self::to_naive_date_opt(i)
1034 .unwrap_or_else(|| panic!("Date64Type::to_naive_date overflowed for date: {i}",))
1035 }
1036
1037 pub fn to_naive_date_opt(i: <Date64Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
1048 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1049 Duration::try_milliseconds(i).and_then(|d| epoch.checked_add_signed(d))
1050 }
1051
1052 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1058 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1059 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1060 }
1061
1062 #[deprecated(
1069 since = "56.0.0",
1070 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
1071 )]
1072 pub fn add_year_months(
1073 date: <Date64Type as ArrowPrimitiveType>::Native,
1074 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1075 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1076 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
1077 panic!("Date64Type::add_year_months overflowed for date: {date}, delta: {delta}",)
1078 })
1079 }
1080
1081 pub fn add_year_months_opt(
1090 date: <Date64Type as ArrowPrimitiveType>::Native,
1091 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1092 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1093 let prior = Date64Type::to_naive_date_opt(date)?;
1094 let months = IntervalYearMonthType::to_months(delta);
1095 let posterior = shift_months(prior, months);
1096 Some(Date64Type::from_naive_date(posterior))
1097 }
1098
1099 #[deprecated(
1106 since = "56.0.0",
1107 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1108 )]
1109 pub fn add_day_time(
1110 date: <Date64Type as ArrowPrimitiveType>::Native,
1111 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1112 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1113 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1114 panic!("Date64Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
1115 })
1116 }
1117
1118 pub fn add_day_time_opt(
1127 date: <Date64Type as ArrowPrimitiveType>::Native,
1128 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1129 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1130 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1131 let res = Date64Type::to_naive_date_opt(date)?;
1132 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1133 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1134 Some(Date64Type::from_naive_date(res))
1135 }
1136
1137 #[deprecated(
1144 since = "56.0.0",
1145 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1146 )]
1147 pub fn add_month_day_nano(
1148 date: <Date64Type as ArrowPrimitiveType>::Native,
1149 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1150 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1151 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1152 panic!("Date64Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1153 })
1154 }
1155
1156 pub fn add_month_day_nano_opt(
1165 date: <Date64Type as ArrowPrimitiveType>::Native,
1166 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1167 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1168 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1169 let res = Date64Type::to_naive_date_opt(date)?;
1170 let res = shift_months(res, months);
1171 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1172 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1173 Some(Date64Type::from_naive_date(res))
1174 }
1175
1176 #[deprecated(
1183 since = "56.0.0",
1184 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1185 )]
1186 pub fn subtract_year_months(
1187 date: <Date64Type as ArrowPrimitiveType>::Native,
1188 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1189 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1190 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1191 panic!("Date64Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1192 })
1193 }
1194
1195 pub fn subtract_year_months_opt(
1204 date: <Date64Type as ArrowPrimitiveType>::Native,
1205 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1206 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1207 let prior = Date64Type::to_naive_date_opt(date)?;
1208 let months = IntervalYearMonthType::to_months(-delta);
1209 let posterior = shift_months(prior, months);
1210 Some(Date64Type::from_naive_date(posterior))
1211 }
1212
1213 #[deprecated(
1220 since = "56.0.0",
1221 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1222 )]
1223 pub fn subtract_day_time(
1224 date: <Date64Type as ArrowPrimitiveType>::Native,
1225 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1226 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1227 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1228 panic!("Date64Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1229 })
1230 }
1231
1232 pub fn subtract_day_time_opt(
1241 date: <Date64Type as ArrowPrimitiveType>::Native,
1242 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1243 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1244 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1245 let res = Date64Type::to_naive_date_opt(date)?;
1246 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1247 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1248 Some(Date64Type::from_naive_date(res))
1249 }
1250
1251 #[deprecated(
1258 since = "56.0.0",
1259 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1260 )]
1261 pub fn subtract_month_day_nano(
1262 date: <Date64Type as ArrowPrimitiveType>::Native,
1263 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1264 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1265 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1266 panic!(
1267 "Date64Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1268 )
1269 })
1270 }
1271
1272 pub fn subtract_month_day_nano_opt(
1281 date: <Date64Type as ArrowPrimitiveType>::Native,
1282 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1283 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1284 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1285 let res = Date64Type::to_naive_date_opt(date)?;
1286 let res = shift_months(res, -months);
1287 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1288 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1289 Some(Date64Type::from_naive_date(res))
1290 }
1291}
1292
1293mod decimal {
1297 use super::*;
1298
1299 pub trait DecimalTypeSealed {}
1300 impl DecimalTypeSealed for Decimal32Type {}
1301 impl DecimalTypeSealed for Decimal64Type {}
1302 impl DecimalTypeSealed for Decimal128Type {}
1303 impl DecimalTypeSealed for Decimal256Type {}
1304}
1305
1306pub trait DecimalType:
1318 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1319{
1320 const BYTE_LENGTH: usize;
1322 const MAX_PRECISION: u8;
1324 const MAX_SCALE: i8;
1326 const MAX_FOR_EACH_PRECISION: &'static [Self::Native];
1328 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1330 const DEFAULT_TYPE: DataType;
1332
1333 const PREFIX: &'static str;
1335
1336 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1338
1339 fn validate_decimal_precision(
1341 value: Self::Native,
1342 precision: u8,
1343 scale: i8,
1344 ) -> Result<(), ArrowError>;
1345
1346 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1348}
1349
1350pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1358 precision: u8,
1359 scale: i8,
1360) -> Result<(), ArrowError> {
1361 if precision == 0 {
1362 return Err(ArrowError::InvalidArgumentError(format!(
1363 "precision cannot be 0, has to be between [1, {}]",
1364 T::MAX_PRECISION
1365 )));
1366 }
1367 if precision > T::MAX_PRECISION {
1368 return Err(ArrowError::InvalidArgumentError(format!(
1369 "precision {} is greater than max {}",
1370 precision,
1371 T::MAX_PRECISION
1372 )));
1373 }
1374 if scale > T::MAX_SCALE {
1375 return Err(ArrowError::InvalidArgumentError(format!(
1376 "scale {} is greater than max {}",
1377 scale,
1378 T::MAX_SCALE
1379 )));
1380 }
1381 if scale > 0 && scale as u8 > precision {
1382 return Err(ArrowError::InvalidArgumentError(format!(
1383 "scale {scale} is greater than precision {precision}"
1384 )));
1385 }
1386
1387 Ok(())
1388}
1389
1390#[derive(Debug)]
1392pub struct Decimal32Type {}
1393
1394impl DecimalType for Decimal32Type {
1395 const BYTE_LENGTH: usize = 4;
1396 const MAX_PRECISION: u8 = DECIMAL32_MAX_PRECISION;
1397 const MAX_SCALE: i8 = DECIMAL32_MAX_SCALE;
1398 const MAX_FOR_EACH_PRECISION: &'static [i32] =
1399 &arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
1400 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1401 const DEFAULT_TYPE: DataType =
1402 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1403 const PREFIX: &'static str = "Decimal32";
1404
1405 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1406 format_decimal_str(&value.to_string(), precision as usize, scale)
1407 }
1408
1409 fn validate_decimal_precision(num: i32, precision: u8, scale: i8) -> Result<(), ArrowError> {
1410 validate_decimal32_precision(num, precision, scale)
1411 }
1412
1413 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1414 is_validate_decimal32_precision(value, precision)
1415 }
1416}
1417
1418impl ArrowPrimitiveType for Decimal32Type {
1419 type Native = i32;
1420
1421 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1422}
1423
1424impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1425
1426#[derive(Debug)]
1428pub struct Decimal64Type {}
1429
1430impl DecimalType for Decimal64Type {
1431 const BYTE_LENGTH: usize = 8;
1432 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1433 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1434 const MAX_FOR_EACH_PRECISION: &'static [i64] =
1435 &arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
1436 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1437 const DEFAULT_TYPE: DataType =
1438 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1439 const PREFIX: &'static str = "Decimal64";
1440
1441 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1442 format_decimal_str(&value.to_string(), precision as usize, scale)
1443 }
1444
1445 fn validate_decimal_precision(num: i64, precision: u8, scale: i8) -> Result<(), ArrowError> {
1446 validate_decimal64_precision(num, precision, scale)
1447 }
1448
1449 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1450 is_validate_decimal64_precision(value, precision)
1451 }
1452}
1453
1454impl ArrowPrimitiveType for Decimal64Type {
1455 type Native = i64;
1456
1457 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1458}
1459
1460impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1461
1462#[derive(Debug)]
1464pub struct Decimal128Type {}
1465
1466impl DecimalType for Decimal128Type {
1467 const BYTE_LENGTH: usize = 16;
1468 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1469 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1470 const MAX_FOR_EACH_PRECISION: &'static [i128] =
1471 &arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
1472 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1473 const DEFAULT_TYPE: DataType =
1474 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1475 const PREFIX: &'static str = "Decimal128";
1476
1477 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1478 format_decimal_str(&value.to_string(), precision as usize, scale)
1479 }
1480
1481 fn validate_decimal_precision(num: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1482 validate_decimal_precision(num, precision, scale)
1483 }
1484
1485 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1486 is_validate_decimal_precision(value, precision)
1487 }
1488}
1489
1490impl ArrowPrimitiveType for Decimal128Type {
1491 type Native = i128;
1492
1493 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1494}
1495
1496impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1497
1498#[derive(Debug)]
1500pub struct Decimal256Type {}
1501
1502impl DecimalType for Decimal256Type {
1503 const BYTE_LENGTH: usize = 32;
1504 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1505 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1506 const MAX_FOR_EACH_PRECISION: &'static [i256] =
1507 &arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
1508 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1509 const DEFAULT_TYPE: DataType =
1510 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1511 const PREFIX: &'static str = "Decimal256";
1512
1513 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1514 format_decimal_str(&value.to_string(), precision as usize, scale)
1515 }
1516
1517 fn validate_decimal_precision(num: i256, precision: u8, scale: i8) -> Result<(), ArrowError> {
1518 validate_decimal256_precision(num, precision, scale)
1519 }
1520
1521 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1522 is_validate_decimal256_precision(value, precision)
1523 }
1524}
1525
1526impl ArrowPrimitiveType for Decimal256Type {
1527 type Native = i256;
1528
1529 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1530}
1531
1532impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1533
1534pub(crate) mod bytes {
1538 use super::*;
1539
1540 pub trait ByteArrayTypeSealed {}
1541 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1542 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1543
1544 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1545 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1546
1547 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1551 }
1552
1553 impl ByteArrayNativeType for [u8] {
1554 #[inline]
1555 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1556 Some(b)
1557 }
1558
1559 #[inline]
1560 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1561 b
1562 }
1563 }
1564
1565 impl ByteArrayNativeType for str {
1566 #[inline]
1567 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1568 std::str::from_utf8(b).ok()
1569 }
1570
1571 #[inline]
1572 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1573 unsafe { std::str::from_utf8_unchecked(b) }
1574 }
1575 }
1576}
1577
1578pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1582 type Offset: OffsetSizeTrait;
1584 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1588
1589 const PREFIX: &'static str;
1591
1592 const DATA_TYPE: DataType;
1594
1595 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1597}
1598
1599pub struct GenericStringType<O: OffsetSizeTrait> {
1601 phantom: PhantomData<O>,
1602}
1603
1604impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1605 type Offset = O;
1606 type Native = str;
1607 const PREFIX: &'static str = "String";
1608
1609 const DATA_TYPE: DataType = if O::IS_LARGE {
1610 DataType::LargeUtf8
1611 } else {
1612 DataType::Utf8
1613 };
1614
1615 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1616 let validated = std::str::from_utf8(values).map_err(|e| {
1618 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1619 })?;
1620
1621 for offset in offsets.iter() {
1623 let o = offset.as_usize();
1624 if !validated.is_char_boundary(o) {
1625 if o < validated.len() {
1626 return Err(ArrowError::InvalidArgumentError(format!(
1627 "Split UTF-8 codepoint at offset {o}"
1628 )));
1629 }
1630 return Err(ArrowError::InvalidArgumentError(format!(
1631 "Offset of {o} exceeds length of values {}",
1632 validated.len()
1633 )));
1634 }
1635 }
1636 Ok(())
1637 }
1638}
1639
1640pub type Utf8Type = GenericStringType<i32>;
1642pub type LargeUtf8Type = GenericStringType<i64>;
1644
1645pub struct GenericBinaryType<O: OffsetSizeTrait> {
1647 phantom: PhantomData<O>,
1648}
1649
1650impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1651 type Offset = O;
1652 type Native = [u8];
1653 const PREFIX: &'static str = "Binary";
1654
1655 const DATA_TYPE: DataType = if O::IS_LARGE {
1656 DataType::LargeBinary
1657 } else {
1658 DataType::Binary
1659 };
1660
1661 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1662 let max_offset = offsets.last().unwrap().as_usize();
1664 if values.len() < max_offset {
1665 return Err(ArrowError::InvalidArgumentError(format!(
1666 "Maximum offset of {max_offset} is larger than values of length {}",
1667 values.len()
1668 )));
1669 }
1670 Ok(())
1671 }
1672}
1673
1674pub type BinaryType = GenericBinaryType<i32>;
1676pub type LargeBinaryType = GenericBinaryType<i64>;
1678
1679mod byte_view {
1680 use crate::types::{BinaryViewType, StringViewType};
1681
1682 pub trait Sealed: Send + Sync {}
1683 impl Sealed for StringViewType {}
1684 impl Sealed for BinaryViewType {}
1685}
1686
1687pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1689 const IS_UTF8: bool;
1691
1692 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1694 DataType::Utf8View
1695 } else {
1696 DataType::BinaryView
1697 };
1698
1699 const PREFIX: &'static str;
1701
1702 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1706
1707 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1709
1710 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1712}
1713
1714#[derive(PartialEq)]
1716pub struct StringViewType {}
1717
1718impl ByteViewType for StringViewType {
1719 const IS_UTF8: bool = true;
1720 const PREFIX: &'static str = "String";
1721
1722 type Native = str;
1723 type Owned = String;
1724
1725 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1726 validate_string_view(views, buffers)
1727 }
1728}
1729
1730#[derive(PartialEq)]
1732pub struct BinaryViewType {}
1733
1734impl ByteViewType for BinaryViewType {
1735 const IS_UTF8: bool = false;
1736 const PREFIX: &'static str = "Binary";
1737 type Native = [u8];
1738 type Owned = Vec<u8>;
1739
1740 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1741 validate_binary_view(views, buffers)
1742 }
1743}
1744
1745#[cfg(test)]
1746mod tests {
1747 use super::*;
1748 use arrow_data::{BufferSpec, layout};
1749
1750 #[test]
1751 fn month_day_nano_should_roundtrip() {
1752 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1753 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1754 }
1755
1756 #[test]
1757 fn month_day_nano_should_roundtrip_neg() {
1758 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1759 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1760 }
1761
1762 #[test]
1763 fn day_time_should_roundtrip() {
1764 let value = IntervalDayTimeType::make_value(1, 2);
1765 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1766 }
1767
1768 #[test]
1769 fn day_time_should_roundtrip_neg() {
1770 let value = IntervalDayTimeType::make_value(-1, -2);
1771 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1772 }
1773
1774 #[test]
1775 fn year_month_should_roundtrip() {
1776 let value = IntervalYearMonthType::make_value(1, 2);
1777 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1778 }
1779
1780 #[test]
1781 fn year_month_should_roundtrip_neg() {
1782 let value = IntervalYearMonthType::make_value(-1, -2);
1783 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1784 }
1785
1786 fn test_layout<T: ArrowPrimitiveType>() {
1787 let layout = layout(&T::DATA_TYPE);
1788
1789 assert_eq!(layout.buffers.len(), 1);
1790
1791 let spec = &layout.buffers[0];
1792 assert_eq!(
1793 spec,
1794 &BufferSpec::FixedWidth {
1795 byte_width: std::mem::size_of::<T::Native>(),
1796 alignment: std::mem::align_of::<T::Native>(),
1797 }
1798 );
1799 }
1800
1801 #[test]
1802 fn test_layouts() {
1803 test_layout::<Int8Type>();
1804 test_layout::<Int16Type>();
1805 test_layout::<Int32Type>();
1806 test_layout::<Int64Type>();
1807 test_layout::<UInt8Type>();
1808 test_layout::<UInt16Type>();
1809 test_layout::<UInt32Type>();
1810 test_layout::<UInt64Type>();
1811 test_layout::<Float16Type>();
1812 test_layout::<Float32Type>();
1813 test_layout::<Float64Type>();
1814 test_layout::<Decimal32Type>();
1815 test_layout::<Decimal64Type>();
1816 test_layout::<Decimal128Type>();
1817 test_layout::<Decimal256Type>();
1818 test_layout::<TimestampNanosecondType>();
1819 test_layout::<TimestampMillisecondType>();
1820 test_layout::<TimestampMicrosecondType>();
1821 test_layout::<TimestampNanosecondType>();
1822 test_layout::<TimestampSecondType>();
1823 test_layout::<Date32Type>();
1824 test_layout::<Date64Type>();
1825 test_layout::<Time32SecondType>();
1826 test_layout::<Time32MillisecondType>();
1827 test_layout::<Time64MicrosecondType>();
1828 test_layout::<Time64NanosecondType>();
1829 test_layout::<IntervalMonthDayNanoType>();
1830 test_layout::<IntervalDayTimeType>();
1831 test_layout::<IntervalYearMonthType>();
1832 test_layout::<DurationNanosecondType>();
1833 test_layout::<DurationMicrosecondType>();
1834 test_layout::<DurationMillisecondType>();
1835 test_layout::<DurationSecondType>();
1836 }
1837}