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: &[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: &[i32] = &arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
1399 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1400 const DEFAULT_TYPE: DataType =
1401 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1402 const PREFIX: &'static str = "Decimal32";
1403
1404 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1405 format_decimal_str(&value.to_string(), precision as usize, scale)
1406 }
1407
1408 fn validate_decimal_precision(num: i32, precision: u8, scale: i8) -> Result<(), ArrowError> {
1409 validate_decimal32_precision(num, precision, scale)
1410 }
1411
1412 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1413 is_validate_decimal32_precision(value, precision)
1414 }
1415}
1416
1417impl ArrowPrimitiveType for Decimal32Type {
1418 type Native = i32;
1419
1420 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1421}
1422
1423impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1424
1425#[derive(Debug)]
1427pub struct Decimal64Type {}
1428
1429impl DecimalType for Decimal64Type {
1430 const BYTE_LENGTH: usize = 8;
1431 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1432 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1433 const MAX_FOR_EACH_PRECISION: &[i64] = &arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
1434 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1435 const DEFAULT_TYPE: DataType =
1436 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1437 const PREFIX: &'static str = "Decimal64";
1438
1439 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1440 format_decimal_str(&value.to_string(), precision as usize, scale)
1441 }
1442
1443 fn validate_decimal_precision(num: i64, precision: u8, scale: i8) -> Result<(), ArrowError> {
1444 validate_decimal64_precision(num, precision, scale)
1445 }
1446
1447 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1448 is_validate_decimal64_precision(value, precision)
1449 }
1450}
1451
1452impl ArrowPrimitiveType for Decimal64Type {
1453 type Native = i64;
1454
1455 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1456}
1457
1458impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1459
1460#[derive(Debug)]
1462pub struct Decimal128Type {}
1463
1464impl DecimalType for Decimal128Type {
1465 const BYTE_LENGTH: usize = 16;
1466 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1467 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1468 const MAX_FOR_EACH_PRECISION: &[i128] = &arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
1469 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1470 const DEFAULT_TYPE: DataType =
1471 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1472 const PREFIX: &'static str = "Decimal128";
1473
1474 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1475 format_decimal_str(&value.to_string(), precision as usize, scale)
1476 }
1477
1478 fn validate_decimal_precision(num: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1479 validate_decimal_precision(num, precision, scale)
1480 }
1481
1482 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1483 is_validate_decimal_precision(value, precision)
1484 }
1485}
1486
1487impl ArrowPrimitiveType for Decimal128Type {
1488 type Native = i128;
1489
1490 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1491}
1492
1493impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1494
1495#[derive(Debug)]
1497pub struct Decimal256Type {}
1498
1499impl DecimalType for Decimal256Type {
1500 const BYTE_LENGTH: usize = 32;
1501 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1502 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1503 const MAX_FOR_EACH_PRECISION: &[i256] = &arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
1504 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1505 const DEFAULT_TYPE: DataType =
1506 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1507 const PREFIX: &'static str = "Decimal256";
1508
1509 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1510 format_decimal_str(&value.to_string(), precision as usize, scale)
1511 }
1512
1513 fn validate_decimal_precision(num: i256, precision: u8, scale: i8) -> Result<(), ArrowError> {
1514 validate_decimal256_precision(num, precision, scale)
1515 }
1516
1517 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1518 is_validate_decimal256_precision(value, precision)
1519 }
1520}
1521
1522impl ArrowPrimitiveType for Decimal256Type {
1523 type Native = i256;
1524
1525 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1526}
1527
1528impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1529
1530pub(crate) mod bytes {
1534 use super::*;
1535
1536 pub trait ByteArrayTypeSealed {}
1537 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1538 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1539
1540 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1541 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1542
1543 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1547 }
1548
1549 impl ByteArrayNativeType for [u8] {
1550 #[inline]
1551 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1552 Some(b)
1553 }
1554
1555 #[inline]
1556 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1557 b
1558 }
1559 }
1560
1561 impl ByteArrayNativeType for str {
1562 #[inline]
1563 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1564 std::str::from_utf8(b).ok()
1565 }
1566
1567 #[inline]
1568 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1569 unsafe { std::str::from_utf8_unchecked(b) }
1570 }
1571 }
1572}
1573
1574pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1578 type Offset: OffsetSizeTrait;
1580 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1584
1585 const PREFIX: &'static str;
1587
1588 const DATA_TYPE: DataType;
1590
1591 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1593}
1594
1595pub struct GenericStringType<O: OffsetSizeTrait> {
1597 phantom: PhantomData<O>,
1598}
1599
1600impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1601 type Offset = O;
1602 type Native = str;
1603 const PREFIX: &'static str = "String";
1604
1605 const DATA_TYPE: DataType = if O::IS_LARGE {
1606 DataType::LargeUtf8
1607 } else {
1608 DataType::Utf8
1609 };
1610
1611 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1612 let validated = std::str::from_utf8(values).map_err(|e| {
1614 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1615 })?;
1616
1617 for offset in offsets.iter() {
1619 let o = offset.as_usize();
1620 if !validated.is_char_boundary(o) {
1621 if o < validated.len() {
1622 return Err(ArrowError::InvalidArgumentError(format!(
1623 "Split UTF-8 codepoint at offset {o}"
1624 )));
1625 }
1626 return Err(ArrowError::InvalidArgumentError(format!(
1627 "Offset of {o} exceeds length of values {}",
1628 validated.len()
1629 )));
1630 }
1631 }
1632 Ok(())
1633 }
1634}
1635
1636pub type Utf8Type = GenericStringType<i32>;
1638pub type LargeUtf8Type = GenericStringType<i64>;
1640
1641pub struct GenericBinaryType<O: OffsetSizeTrait> {
1643 phantom: PhantomData<O>,
1644}
1645
1646impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1647 type Offset = O;
1648 type Native = [u8];
1649 const PREFIX: &'static str = "Binary";
1650
1651 const DATA_TYPE: DataType = if O::IS_LARGE {
1652 DataType::LargeBinary
1653 } else {
1654 DataType::Binary
1655 };
1656
1657 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1658 let max_offset = offsets.last().unwrap().as_usize();
1660 if values.len() < max_offset {
1661 return Err(ArrowError::InvalidArgumentError(format!(
1662 "Maximum offset of {max_offset} is larger than values of length {}",
1663 values.len()
1664 )));
1665 }
1666 Ok(())
1667 }
1668}
1669
1670pub type BinaryType = GenericBinaryType<i32>;
1672pub type LargeBinaryType = GenericBinaryType<i64>;
1674
1675mod byte_view {
1676 use crate::types::{BinaryViewType, StringViewType};
1677
1678 pub trait Sealed: Send + Sync {}
1679 impl Sealed for StringViewType {}
1680 impl Sealed for BinaryViewType {}
1681}
1682
1683pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1685 const IS_UTF8: bool;
1687
1688 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1690 DataType::Utf8View
1691 } else {
1692 DataType::BinaryView
1693 };
1694
1695 const PREFIX: &'static str;
1697
1698 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1702
1703 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1705
1706 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1708}
1709
1710#[derive(PartialEq)]
1712pub struct StringViewType {}
1713
1714impl ByteViewType for StringViewType {
1715 const IS_UTF8: bool = true;
1716 const PREFIX: &'static str = "String";
1717
1718 type Native = str;
1719 type Owned = String;
1720
1721 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1722 validate_string_view(views, buffers)
1723 }
1724}
1725
1726#[derive(PartialEq)]
1728pub struct BinaryViewType {}
1729
1730impl ByteViewType for BinaryViewType {
1731 const IS_UTF8: bool = false;
1732 const PREFIX: &'static str = "Binary";
1733 type Native = [u8];
1734 type Owned = Vec<u8>;
1735
1736 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1737 validate_binary_view(views, buffers)
1738 }
1739}
1740
1741#[cfg(test)]
1742mod tests {
1743 use super::*;
1744 use arrow_data::{BufferSpec, layout};
1745
1746 #[test]
1747 fn month_day_nano_should_roundtrip() {
1748 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1749 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1750 }
1751
1752 #[test]
1753 fn month_day_nano_should_roundtrip_neg() {
1754 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1755 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1756 }
1757
1758 #[test]
1759 fn day_time_should_roundtrip() {
1760 let value = IntervalDayTimeType::make_value(1, 2);
1761 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1762 }
1763
1764 #[test]
1765 fn day_time_should_roundtrip_neg() {
1766 let value = IntervalDayTimeType::make_value(-1, -2);
1767 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1768 }
1769
1770 #[test]
1771 fn year_month_should_roundtrip() {
1772 let value = IntervalYearMonthType::make_value(1, 2);
1773 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1774 }
1775
1776 #[test]
1777 fn year_month_should_roundtrip_neg() {
1778 let value = IntervalYearMonthType::make_value(-1, -2);
1779 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1780 }
1781
1782 fn test_layout<T: ArrowPrimitiveType>() {
1783 let layout = layout(&T::DATA_TYPE);
1784
1785 assert_eq!(layout.buffers.len(), 1);
1786
1787 let spec = &layout.buffers[0];
1788 assert_eq!(
1789 spec,
1790 &BufferSpec::FixedWidth {
1791 byte_width: std::mem::size_of::<T::Native>(),
1792 alignment: std::mem::align_of::<T::Native>(),
1793 }
1794 );
1795 }
1796
1797 #[test]
1798 fn test_layouts() {
1799 test_layout::<Int8Type>();
1800 test_layout::<Int16Type>();
1801 test_layout::<Int32Type>();
1802 test_layout::<Int64Type>();
1803 test_layout::<UInt8Type>();
1804 test_layout::<UInt16Type>();
1805 test_layout::<UInt32Type>();
1806 test_layout::<UInt64Type>();
1807 test_layout::<Float16Type>();
1808 test_layout::<Float32Type>();
1809 test_layout::<Float64Type>();
1810 test_layout::<Decimal32Type>();
1811 test_layout::<Decimal64Type>();
1812 test_layout::<Decimal128Type>();
1813 test_layout::<Decimal256Type>();
1814 test_layout::<TimestampNanosecondType>();
1815 test_layout::<TimestampMillisecondType>();
1816 test_layout::<TimestampMicrosecondType>();
1817 test_layout::<TimestampNanosecondType>();
1818 test_layout::<TimestampSecondType>();
1819 test_layout::<Date32Type>();
1820 test_layout::<Date64Type>();
1821 test_layout::<Time32SecondType>();
1822 test_layout::<Time32MillisecondType>();
1823 test_layout::<Time64MicrosecondType>();
1824 test_layout::<Time64NanosecondType>();
1825 test_layout::<IntervalMonthDayNanoType>();
1826 test_layout::<IntervalDayTimeType>();
1827 test_layout::<IntervalYearMonthType>();
1828 test_layout::<DurationNanosecondType>();
1829 test_layout::<DurationMicrosecondType>();
1830 test_layout::<DurationMillisecondType>();
1831 test_layout::<DurationSecondType>();
1832 }
1833}