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_decimal32_precision,
29 is_validate_decimal64_precision, is_validate_decimal_precision, validate_decimal256_precision,
30 validate_decimal32_precision, validate_decimal64_precision, validate_decimal_precision,
31};
32use arrow_data::{validate_binary_view, validate_string_view};
33use arrow_schema::{
34 ArrowError, DataType, IntervalUnit, TimeUnit, DECIMAL128_MAX_PRECISION, DECIMAL128_MAX_SCALE,
35 DECIMAL256_MAX_PRECISION, DECIMAL256_MAX_SCALE, DECIMAL32_DEFAULT_SCALE,
36 DECIMAL32_MAX_PRECISION, DECIMAL32_MAX_SCALE, DECIMAL64_DEFAULT_SCALE, DECIMAL64_MAX_PRECISION,
37 DECIMAL64_MAX_SCALE, DECIMAL_DEFAULT_SCALE,
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 TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1328 const DEFAULT_TYPE: DataType;
1330
1331 const PREFIX: &'static str;
1333
1334 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1336
1337 fn validate_decimal_precision(value: Self::Native, precision: u8) -> Result<(), ArrowError>;
1339
1340 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1342}
1343
1344pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1352 precision: u8,
1353 scale: i8,
1354) -> Result<(), ArrowError> {
1355 if precision == 0 {
1356 return Err(ArrowError::InvalidArgumentError(format!(
1357 "precision cannot be 0, has to be between [1, {}]",
1358 T::MAX_PRECISION
1359 )));
1360 }
1361 if precision > T::MAX_PRECISION {
1362 return Err(ArrowError::InvalidArgumentError(format!(
1363 "precision {} is greater than max {}",
1364 precision,
1365 T::MAX_PRECISION
1366 )));
1367 }
1368 if scale > T::MAX_SCALE {
1369 return Err(ArrowError::InvalidArgumentError(format!(
1370 "scale {} is greater than max {}",
1371 scale,
1372 T::MAX_SCALE
1373 )));
1374 }
1375 if scale > 0 && scale as u8 > precision {
1376 return Err(ArrowError::InvalidArgumentError(format!(
1377 "scale {scale} is greater than precision {precision}"
1378 )));
1379 }
1380
1381 Ok(())
1382}
1383
1384#[derive(Debug)]
1386pub struct Decimal32Type {}
1387
1388impl DecimalType for Decimal32Type {
1389 const BYTE_LENGTH: usize = 4;
1390 const MAX_PRECISION: u8 = DECIMAL32_MAX_PRECISION;
1391 const MAX_SCALE: i8 = DECIMAL32_MAX_SCALE;
1392 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1393 const DEFAULT_TYPE: DataType =
1394 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1395 const PREFIX: &'static str = "Decimal32";
1396
1397 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1398 format_decimal_str(&value.to_string(), precision as usize, scale)
1399 }
1400
1401 fn validate_decimal_precision(num: i32, precision: u8) -> Result<(), ArrowError> {
1402 validate_decimal32_precision(num, precision)
1403 }
1404
1405 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1406 is_validate_decimal32_precision(value, precision)
1407 }
1408}
1409
1410impl ArrowPrimitiveType for Decimal32Type {
1411 type Native = i32;
1412
1413 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1414}
1415
1416impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1417
1418#[derive(Debug)]
1420pub struct Decimal64Type {}
1421
1422impl DecimalType for Decimal64Type {
1423 const BYTE_LENGTH: usize = 8;
1424 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1425 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1426 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1427 const DEFAULT_TYPE: DataType =
1428 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1429 const PREFIX: &'static str = "Decimal64";
1430
1431 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1432 format_decimal_str(&value.to_string(), precision as usize, scale)
1433 }
1434
1435 fn validate_decimal_precision(num: i64, precision: u8) -> Result<(), ArrowError> {
1436 validate_decimal64_precision(num, precision)
1437 }
1438
1439 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1440 is_validate_decimal64_precision(value, precision)
1441 }
1442}
1443
1444impl ArrowPrimitiveType for Decimal64Type {
1445 type Native = i64;
1446
1447 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1448}
1449
1450impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1451
1452#[derive(Debug)]
1454pub struct Decimal128Type {}
1455
1456impl DecimalType for Decimal128Type {
1457 const BYTE_LENGTH: usize = 16;
1458 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1459 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1460 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1461 const DEFAULT_TYPE: DataType =
1462 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1463 const PREFIX: &'static str = "Decimal128";
1464
1465 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1466 format_decimal_str(&value.to_string(), precision as usize, scale)
1467 }
1468
1469 fn validate_decimal_precision(num: i128, precision: u8) -> Result<(), ArrowError> {
1470 validate_decimal_precision(num, precision)
1471 }
1472
1473 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1474 is_validate_decimal_precision(value, precision)
1475 }
1476}
1477
1478impl ArrowPrimitiveType for Decimal128Type {
1479 type Native = i128;
1480
1481 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1482}
1483
1484impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1485
1486#[derive(Debug)]
1488pub struct Decimal256Type {}
1489
1490impl DecimalType for Decimal256Type {
1491 const BYTE_LENGTH: usize = 32;
1492 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1493 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1494 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1495 const DEFAULT_TYPE: DataType =
1496 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1497 const PREFIX: &'static str = "Decimal256";
1498
1499 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1500 format_decimal_str(&value.to_string(), precision as usize, scale)
1501 }
1502
1503 fn validate_decimal_precision(num: i256, precision: u8) -> Result<(), ArrowError> {
1504 validate_decimal256_precision(num, precision)
1505 }
1506
1507 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1508 is_validate_decimal256_precision(value, precision)
1509 }
1510}
1511
1512impl ArrowPrimitiveType for Decimal256Type {
1513 type Native = i256;
1514
1515 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1516}
1517
1518impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1519
1520fn format_decimal_str(value_str: &str, precision: usize, scale: i8) -> String {
1521 let (sign, rest) = match value_str.strip_prefix('-') {
1522 Some(stripped) => ("-", stripped),
1523 None => ("", value_str),
1524 };
1525 let bound = precision.min(rest.len()) + sign.len();
1526 let value_str = &value_str[0..bound];
1527
1528 if scale == 0 {
1529 value_str.to_string()
1530 } else if scale < 0 {
1531 let padding = value_str.len() + scale.unsigned_abs() as usize;
1532 format!("{value_str:0<padding$}")
1533 } else if rest.len() > scale as usize {
1534 let (whole, decimal) = value_str.split_at(value_str.len() - scale as usize);
1536 format!("{whole}.{decimal}")
1537 } else {
1538 format!("{}0.{:0>width$}", sign, rest, width = scale as usize)
1540 }
1541}
1542
1543pub(crate) mod bytes {
1547 use super::*;
1548
1549 pub trait ByteArrayTypeSealed {}
1550 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1551 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1552
1553 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1554 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1555
1556 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1560 }
1561
1562 impl ByteArrayNativeType for [u8] {
1563 #[inline]
1564 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1565 Some(b)
1566 }
1567
1568 #[inline]
1569 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1570 b
1571 }
1572 }
1573
1574 impl ByteArrayNativeType for str {
1575 #[inline]
1576 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1577 std::str::from_utf8(b).ok()
1578 }
1579
1580 #[inline]
1581 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1582 std::str::from_utf8_unchecked(b)
1583 }
1584 }
1585}
1586
1587pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1591 type Offset: OffsetSizeTrait;
1593 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1597
1598 const PREFIX: &'static str;
1600
1601 const DATA_TYPE: DataType;
1603
1604 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1606}
1607
1608pub struct GenericStringType<O: OffsetSizeTrait> {
1610 phantom: PhantomData<O>,
1611}
1612
1613impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1614 type Offset = O;
1615 type Native = str;
1616 const PREFIX: &'static str = "String";
1617
1618 const DATA_TYPE: DataType = if O::IS_LARGE {
1619 DataType::LargeUtf8
1620 } else {
1621 DataType::Utf8
1622 };
1623
1624 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1625 let validated = std::str::from_utf8(values).map_err(|e| {
1627 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1628 })?;
1629
1630 for offset in offsets.iter() {
1632 let o = offset.as_usize();
1633 if !validated.is_char_boundary(o) {
1634 if o < validated.len() {
1635 return Err(ArrowError::InvalidArgumentError(format!(
1636 "Split UTF-8 codepoint at offset {o}"
1637 )));
1638 }
1639 return Err(ArrowError::InvalidArgumentError(format!(
1640 "Offset of {o} exceeds length of values {}",
1641 validated.len()
1642 )));
1643 }
1644 }
1645 Ok(())
1646 }
1647}
1648
1649pub type Utf8Type = GenericStringType<i32>;
1651pub type LargeUtf8Type = GenericStringType<i64>;
1653
1654pub struct GenericBinaryType<O: OffsetSizeTrait> {
1656 phantom: PhantomData<O>,
1657}
1658
1659impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1660 type Offset = O;
1661 type Native = [u8];
1662 const PREFIX: &'static str = "Binary";
1663
1664 const DATA_TYPE: DataType = if O::IS_LARGE {
1665 DataType::LargeBinary
1666 } else {
1667 DataType::Binary
1668 };
1669
1670 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1671 let max_offset = offsets.last().unwrap().as_usize();
1673 if values.len() < max_offset {
1674 return Err(ArrowError::InvalidArgumentError(format!(
1675 "Maximum offset of {max_offset} is larger than values of length {}",
1676 values.len()
1677 )));
1678 }
1679 Ok(())
1680 }
1681}
1682
1683pub type BinaryType = GenericBinaryType<i32>;
1685pub type LargeBinaryType = GenericBinaryType<i64>;
1687
1688mod byte_view {
1689 use crate::types::{BinaryViewType, StringViewType};
1690
1691 pub trait Sealed: Send + Sync {}
1692 impl Sealed for StringViewType {}
1693 impl Sealed for BinaryViewType {}
1694}
1695
1696pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1698 const IS_UTF8: bool;
1700
1701 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1703 DataType::Utf8View
1704 } else {
1705 DataType::BinaryView
1706 };
1707
1708 const PREFIX: &'static str;
1710
1711 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1715
1716 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1718
1719 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1721}
1722
1723#[derive(PartialEq)]
1725pub struct StringViewType {}
1726
1727impl ByteViewType for StringViewType {
1728 const IS_UTF8: bool = true;
1729 const PREFIX: &'static str = "String";
1730
1731 type Native = str;
1732 type Owned = String;
1733
1734 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1735 validate_string_view(views, buffers)
1736 }
1737}
1738
1739#[derive(PartialEq)]
1741pub struct BinaryViewType {}
1742
1743impl ByteViewType for BinaryViewType {
1744 const IS_UTF8: bool = false;
1745 const PREFIX: &'static str = "Binary";
1746 type Native = [u8];
1747 type Owned = Vec<u8>;
1748
1749 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1750 validate_binary_view(views, buffers)
1751 }
1752}
1753
1754#[cfg(test)]
1755mod tests {
1756 use super::*;
1757 use arrow_data::{layout, BufferSpec};
1758
1759 #[test]
1760 fn month_day_nano_should_roundtrip() {
1761 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1762 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1763 }
1764
1765 #[test]
1766 fn month_day_nano_should_roundtrip_neg() {
1767 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1768 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1769 }
1770
1771 #[test]
1772 fn day_time_should_roundtrip() {
1773 let value = IntervalDayTimeType::make_value(1, 2);
1774 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1775 }
1776
1777 #[test]
1778 fn day_time_should_roundtrip_neg() {
1779 let value = IntervalDayTimeType::make_value(-1, -2);
1780 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1781 }
1782
1783 #[test]
1784 fn year_month_should_roundtrip() {
1785 let value = IntervalYearMonthType::make_value(1, 2);
1786 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1787 }
1788
1789 #[test]
1790 fn year_month_should_roundtrip_neg() {
1791 let value = IntervalYearMonthType::make_value(-1, -2);
1792 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1793 }
1794
1795 fn test_layout<T: ArrowPrimitiveType>() {
1796 let layout = layout(&T::DATA_TYPE);
1797
1798 assert_eq!(layout.buffers.len(), 1);
1799
1800 let spec = &layout.buffers[0];
1801 assert_eq!(
1802 spec,
1803 &BufferSpec::FixedWidth {
1804 byte_width: std::mem::size_of::<T::Native>(),
1805 alignment: std::mem::align_of::<T::Native>(),
1806 }
1807 );
1808 }
1809
1810 #[test]
1811 fn test_layouts() {
1812 test_layout::<Int8Type>();
1813 test_layout::<Int16Type>();
1814 test_layout::<Int32Type>();
1815 test_layout::<Int64Type>();
1816 test_layout::<UInt8Type>();
1817 test_layout::<UInt16Type>();
1818 test_layout::<UInt32Type>();
1819 test_layout::<UInt64Type>();
1820 test_layout::<Float16Type>();
1821 test_layout::<Float32Type>();
1822 test_layout::<Float64Type>();
1823 test_layout::<Decimal128Type>();
1824 test_layout::<Decimal256Type>();
1825 test_layout::<TimestampNanosecondType>();
1826 test_layout::<TimestampMillisecondType>();
1827 test_layout::<TimestampMicrosecondType>();
1828 test_layout::<TimestampNanosecondType>();
1829 test_layout::<TimestampSecondType>();
1830 test_layout::<Date32Type>();
1831 test_layout::<Date64Type>();
1832 test_layout::<Time32SecondType>();
1833 test_layout::<Time32MillisecondType>();
1834 test_layout::<Time64MicrosecondType>();
1835 test_layout::<Time64NanosecondType>();
1836 test_layout::<IntervalMonthDayNanoType>();
1837 test_layout::<IntervalDayTimeType>();
1838 test_layout::<IntervalYearMonthType>();
1839 test_layout::<DurationNanosecondType>();
1840 test_layout::<DurationMicrosecondType>();
1841 test_layout::<DurationMillisecondType>();
1842 test_layout::<DurationSecondType>();
1843 }
1844}