1use crate::delta::{
21 add_days_datetime, add_months_date, add_months_datetime, 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::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 #[deprecated(since = "58.0.0", note = "Use to_naive_date_opt instead.")]
908 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
909 Self::to_naive_date_opt(i)
910 .unwrap_or_else(|| panic!("Date32Type::to_naive_date overflowed for date: {i}",))
911 }
912
913 pub fn to_naive_date_opt(i: <Date32Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
921 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
922 Duration::try_days(i as i64).and_then(|d| epoch.checked_add_signed(d))
923 }
924
925 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
931 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
932 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
933 }
934
935 #[deprecated(
942 since = "58.0.0",
943 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
944 )]
945 pub fn add_year_months(
946 date: <Date32Type as ArrowPrimitiveType>::Native,
947 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
948 ) -> <Date32Type as ArrowPrimitiveType>::Native {
949 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
950 panic!("Date32Type::add_year_months overflowed for date: {date}, delta: {delta}",)
951 })
952 }
953
954 pub fn add_year_months_opt(
963 date: <Date32Type as ArrowPrimitiveType>::Native,
964 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
965 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
966 let prior = Date32Type::to_naive_date_opt(date)?;
967 let months = IntervalYearMonthType::to_months(delta);
968 let posterior = add_months_date(prior, months)?;
969 Some(Date32Type::from_naive_date(posterior))
970 }
971
972 #[deprecated(
979 since = "58.0.0",
980 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
981 )]
982 pub fn add_day_time(
983 date: <Date32Type as ArrowPrimitiveType>::Native,
984 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
985 ) -> <Date32Type as ArrowPrimitiveType>::Native {
986 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
987 panic!("Date32Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
988 })
989 }
990
991 pub fn add_day_time_opt(
1000 date: <Date32Type as ArrowPrimitiveType>::Native,
1001 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1002 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1003 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1004 let res = Date32Type::to_naive_date_opt(date)?;
1005 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1006 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1007 Some(Date32Type::from_naive_date(res))
1008 }
1009
1010 #[deprecated(
1017 since = "58.0.0",
1018 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1019 )]
1020 pub fn add_month_day_nano(
1021 date: <Date32Type as ArrowPrimitiveType>::Native,
1022 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1023 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1024 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1025 panic!("Date32Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1026 })
1027 }
1028
1029 pub fn add_month_day_nano_opt(
1038 date: <Date32Type as ArrowPrimitiveType>::Native,
1039 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1040 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1041 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1042 let res = Date32Type::to_naive_date_opt(date)?;
1043 let res = add_months_date(res, months)?;
1044 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1045 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1046 Some(Date32Type::from_naive_date(res))
1047 }
1048
1049 #[deprecated(
1056 since = "58.0.0",
1057 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1058 )]
1059 pub fn subtract_year_months(
1060 date: <Date32Type as ArrowPrimitiveType>::Native,
1061 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1062 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1063 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1064 panic!("Date32Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1065 })
1066 }
1067
1068 pub fn subtract_year_months_opt(
1077 date: <Date32Type as ArrowPrimitiveType>::Native,
1078 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1079 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1080 let prior = Date32Type::to_naive_date_opt(date)?;
1081 let months = IntervalYearMonthType::to_months(-delta);
1082 let posterior = add_months_date(prior, months)?;
1083 Some(Date32Type::from_naive_date(posterior))
1084 }
1085
1086 #[deprecated(
1093 since = "58.0.0",
1094 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1095 )]
1096 pub fn subtract_day_time(
1097 date: <Date32Type as ArrowPrimitiveType>::Native,
1098 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1099 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1100 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1101 panic!("Date32Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1102 })
1103 }
1104
1105 pub fn subtract_day_time_opt(
1114 date: <Date32Type as ArrowPrimitiveType>::Native,
1115 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1116 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1117 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1118 let res = Date32Type::to_naive_date_opt(date)?;
1119 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1120 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1121 Some(Date32Type::from_naive_date(res))
1122 }
1123
1124 #[deprecated(
1131 since = "58.0.0",
1132 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1133 )]
1134 pub fn subtract_month_day_nano(
1135 date: <Date32Type as ArrowPrimitiveType>::Native,
1136 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1137 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1138 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1139 panic!(
1140 "Date32Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1141 )
1142 })
1143 }
1144
1145 pub fn subtract_month_day_nano_opt(
1154 date: <Date32Type as ArrowPrimitiveType>::Native,
1155 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1156 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1157 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1158 let res = Date32Type::to_naive_date_opt(date)?;
1159 let res = add_months_date(res, -months)?;
1160 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1161 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1162 Some(Date32Type::from_naive_date(res))
1163 }
1164}
1165
1166impl Date64Type {
1167 #[deprecated(since = "56.0.0", note = "Use to_naive_date_opt instead.")]
1173 pub fn to_naive_date(i: <Date64Type as ArrowPrimitiveType>::Native) -> NaiveDate {
1174 Self::to_naive_date_opt(i)
1175 .unwrap_or_else(|| panic!("Date64Type::to_naive_date overflowed for date: {i}",))
1176 }
1177
1178 pub fn to_naive_date_opt(i: <Date64Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
1189 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1190 Duration::try_milliseconds(i).and_then(|d| epoch.checked_add_signed(d))
1191 }
1192
1193 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1199 let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
1200 d.sub(epoch).num_milliseconds() as <Date64Type as ArrowPrimitiveType>::Native
1201 }
1202
1203 #[deprecated(
1210 since = "56.0.0",
1211 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
1212 )]
1213 pub fn add_year_months(
1214 date: <Date64Type as ArrowPrimitiveType>::Native,
1215 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1216 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1217 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
1218 panic!("Date64Type::add_year_months overflowed for date: {date}, delta: {delta}",)
1219 })
1220 }
1221
1222 pub fn add_year_months_opt(
1231 date: <Date64Type as ArrowPrimitiveType>::Native,
1232 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1233 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1234 let prior = Date64Type::to_naive_date_opt(date)?;
1235 let months = IntervalYearMonthType::to_months(delta);
1236 let posterior = add_months_date(prior, months)?;
1237 Some(Date64Type::from_naive_date(posterior))
1238 }
1239
1240 #[deprecated(
1247 since = "56.0.0",
1248 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1249 )]
1250 pub fn add_day_time(
1251 date: <Date64Type as ArrowPrimitiveType>::Native,
1252 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1253 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1254 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1255 panic!("Date64Type::add_day_time overflowed for date: {date}, delta: {delta:?}",)
1256 })
1257 }
1258
1259 pub fn add_day_time_opt(
1268 date: <Date64Type as ArrowPrimitiveType>::Native,
1269 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1270 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1271 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1272 let res = Date64Type::to_naive_date_opt(date)?;
1273 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1274 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1275 Some(Date64Type::from_naive_date(res))
1276 }
1277
1278 #[deprecated(
1285 since = "56.0.0",
1286 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1287 )]
1288 pub fn add_month_day_nano(
1289 date: <Date64Type as ArrowPrimitiveType>::Native,
1290 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1291 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1292 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1293 panic!("Date64Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}",)
1294 })
1295 }
1296
1297 pub fn add_month_day_nano_opt(
1306 date: <Date64Type as ArrowPrimitiveType>::Native,
1307 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1308 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1309 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1310 let res = Date64Type::to_naive_date_opt(date)?;
1311 let res = add_months_date(res, months)?;
1312 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1313 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1314 Some(Date64Type::from_naive_date(res))
1315 }
1316
1317 #[deprecated(
1324 since = "56.0.0",
1325 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1326 )]
1327 pub fn subtract_year_months(
1328 date: <Date64Type as ArrowPrimitiveType>::Native,
1329 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1330 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1331 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1332 panic!("Date64Type::subtract_year_months overflowed for date: {date}, delta: {delta}",)
1333 })
1334 }
1335
1336 pub fn subtract_year_months_opt(
1345 date: <Date64Type as ArrowPrimitiveType>::Native,
1346 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1347 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1348 let prior = Date64Type::to_naive_date_opt(date)?;
1349 let months = IntervalYearMonthType::to_months(-delta);
1350 let posterior = add_months_date(prior, months)?;
1351 Some(Date64Type::from_naive_date(posterior))
1352 }
1353
1354 #[deprecated(
1361 since = "56.0.0",
1362 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1363 )]
1364 pub fn subtract_day_time(
1365 date: <Date64Type as ArrowPrimitiveType>::Native,
1366 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1367 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1368 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1369 panic!("Date64Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}",)
1370 })
1371 }
1372
1373 pub fn subtract_day_time_opt(
1382 date: <Date64Type as ArrowPrimitiveType>::Native,
1383 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1384 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1385 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1386 let res = Date64Type::to_naive_date_opt(date)?;
1387 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1388 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1389 Some(Date64Type::from_naive_date(res))
1390 }
1391
1392 #[deprecated(
1399 since = "56.0.0",
1400 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1401 )]
1402 pub fn subtract_month_day_nano(
1403 date: <Date64Type as ArrowPrimitiveType>::Native,
1404 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1405 ) -> <Date64Type as ArrowPrimitiveType>::Native {
1406 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1407 panic!(
1408 "Date64Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1409 )
1410 })
1411 }
1412
1413 pub fn subtract_month_day_nano_opt(
1422 date: <Date64Type as ArrowPrimitiveType>::Native,
1423 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1424 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1425 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1426 let res = Date64Type::to_naive_date_opt(date)?;
1427 let res = add_months_date(res, -months)?;
1428 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1429 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1430 Some(Date64Type::from_naive_date(res))
1431 }
1432}
1433
1434mod decimal {
1438 use super::*;
1439
1440 pub trait DecimalTypeSealed {}
1441 impl DecimalTypeSealed for Decimal32Type {}
1442 impl DecimalTypeSealed for Decimal64Type {}
1443 impl DecimalTypeSealed for Decimal128Type {}
1444 impl DecimalTypeSealed for Decimal256Type {}
1445}
1446
1447pub trait DecimalType:
1459 'static + Send + Sync + ArrowPrimitiveType + decimal::DecimalTypeSealed
1460{
1461 const BYTE_LENGTH: usize;
1463 const MAX_PRECISION: u8;
1465 const MAX_SCALE: i8;
1467 const MAX_FOR_EACH_PRECISION: &'static [Self::Native];
1469 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1471 const DEFAULT_TYPE: DataType;
1473
1474 const PREFIX: &'static str;
1476
1477 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
1479
1480 fn validate_decimal_precision(
1482 value: Self::Native,
1483 precision: u8,
1484 scale: i8,
1485 ) -> Result<(), ArrowError>;
1486
1487 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1489}
1490
1491pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1499 precision: u8,
1500 scale: i8,
1501) -> Result<(), ArrowError> {
1502 if precision == 0 {
1503 return Err(ArrowError::InvalidArgumentError(format!(
1504 "precision cannot be 0, has to be between [1, {}]",
1505 T::MAX_PRECISION
1506 )));
1507 }
1508 if precision > T::MAX_PRECISION {
1509 return Err(ArrowError::InvalidArgumentError(format!(
1510 "precision {} is greater than max {}",
1511 precision,
1512 T::MAX_PRECISION
1513 )));
1514 }
1515 if scale > T::MAX_SCALE {
1516 return Err(ArrowError::InvalidArgumentError(format!(
1517 "scale {} is greater than max {}",
1518 scale,
1519 T::MAX_SCALE
1520 )));
1521 }
1522 if scale > 0 && scale as u8 > precision {
1523 return Err(ArrowError::InvalidArgumentError(format!(
1524 "scale {scale} is greater than precision {precision}"
1525 )));
1526 }
1527
1528 Ok(())
1529}
1530
1531#[derive(Debug)]
1533pub struct Decimal32Type {}
1534
1535impl DecimalType for Decimal32Type {
1536 const BYTE_LENGTH: usize = 4;
1537 const MAX_PRECISION: u8 = DECIMAL32_MAX_PRECISION;
1538 const MAX_SCALE: i8 = DECIMAL32_MAX_SCALE;
1539 const MAX_FOR_EACH_PRECISION: &'static [i32] =
1540 &arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
1541 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1542 const DEFAULT_TYPE: DataType =
1543 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1544 const PREFIX: &'static str = "Decimal32";
1545
1546 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1547 format_decimal_str(&value.to_string(), precision as usize, scale)
1548 }
1549
1550 fn validate_decimal_precision(num: i32, precision: u8, scale: i8) -> Result<(), ArrowError> {
1551 validate_decimal32_precision(num, precision, scale)
1552 }
1553
1554 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1555 is_validate_decimal32_precision(value, precision)
1556 }
1557}
1558
1559impl ArrowPrimitiveType for Decimal32Type {
1560 type Native = i32;
1561
1562 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1563}
1564
1565impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1566
1567#[derive(Debug)]
1569pub struct Decimal64Type {}
1570
1571impl DecimalType for Decimal64Type {
1572 const BYTE_LENGTH: usize = 8;
1573 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1574 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1575 const MAX_FOR_EACH_PRECISION: &'static [i64] =
1576 &arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
1577 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1578 const DEFAULT_TYPE: DataType =
1579 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1580 const PREFIX: &'static str = "Decimal64";
1581
1582 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1583 format_decimal_str(&value.to_string(), precision as usize, scale)
1584 }
1585
1586 fn validate_decimal_precision(num: i64, precision: u8, scale: i8) -> Result<(), ArrowError> {
1587 validate_decimal64_precision(num, precision, scale)
1588 }
1589
1590 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1591 is_validate_decimal64_precision(value, precision)
1592 }
1593}
1594
1595impl ArrowPrimitiveType for Decimal64Type {
1596 type Native = i64;
1597
1598 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1599}
1600
1601impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1602
1603#[derive(Debug)]
1605pub struct Decimal128Type {}
1606
1607impl DecimalType for Decimal128Type {
1608 const BYTE_LENGTH: usize = 16;
1609 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1610 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1611 const MAX_FOR_EACH_PRECISION: &'static [i128] =
1612 &arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
1613 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1614 const DEFAULT_TYPE: DataType =
1615 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1616 const PREFIX: &'static str = "Decimal128";
1617
1618 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1619 format_decimal_str(&value.to_string(), precision as usize, scale)
1620 }
1621
1622 fn validate_decimal_precision(num: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1623 validate_decimal_precision(num, precision, scale)
1624 }
1625
1626 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1627 is_validate_decimal_precision(value, precision)
1628 }
1629}
1630
1631impl ArrowPrimitiveType for Decimal128Type {
1632 type Native = i128;
1633
1634 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1635}
1636
1637impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1638
1639#[derive(Debug)]
1641pub struct Decimal256Type {}
1642
1643impl DecimalType for Decimal256Type {
1644 const BYTE_LENGTH: usize = 32;
1645 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1646 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1647 const MAX_FOR_EACH_PRECISION: &'static [i256] =
1648 &arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
1649 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1650 const DEFAULT_TYPE: DataType =
1651 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1652 const PREFIX: &'static str = "Decimal256";
1653
1654 fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String {
1655 format_decimal_str(&value.to_string(), precision as usize, scale)
1656 }
1657
1658 fn validate_decimal_precision(num: i256, precision: u8, scale: i8) -> Result<(), ArrowError> {
1659 validate_decimal256_precision(num, precision, scale)
1660 }
1661
1662 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1663 is_validate_decimal256_precision(value, precision)
1664 }
1665}
1666
1667impl ArrowPrimitiveType for Decimal256Type {
1668 type Native = i256;
1669
1670 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1671}
1672
1673impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1674
1675pub(crate) mod bytes {
1679 use super::*;
1680
1681 pub trait ByteArrayTypeSealed {}
1682 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1683 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1684
1685 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1686 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1687
1688 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1692 }
1693
1694 impl ByteArrayNativeType for [u8] {
1695 #[inline]
1696 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1697 Some(b)
1698 }
1699
1700 #[inline]
1701 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1702 b
1703 }
1704 }
1705
1706 impl ByteArrayNativeType for str {
1707 #[inline]
1708 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1709 std::str::from_utf8(b).ok()
1710 }
1711
1712 #[inline]
1713 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1714 unsafe { std::str::from_utf8_unchecked(b) }
1715 }
1716 }
1717}
1718
1719pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1723 type Offset: OffsetSizeTrait;
1725 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1729
1730 const PREFIX: &'static str;
1732
1733 const DATA_TYPE: DataType;
1735
1736 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1738}
1739
1740pub struct GenericStringType<O: OffsetSizeTrait> {
1742 phantom: PhantomData<O>,
1743}
1744
1745impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1746 type Offset = O;
1747 type Native = str;
1748 const PREFIX: &'static str = "String";
1749
1750 const DATA_TYPE: DataType = if O::IS_LARGE {
1751 DataType::LargeUtf8
1752 } else {
1753 DataType::Utf8
1754 };
1755
1756 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1757 let validated = std::str::from_utf8(values).map_err(|e| {
1759 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1760 })?;
1761
1762 for offset in offsets.iter() {
1764 let o = offset.as_usize();
1765 if !validated.is_char_boundary(o) {
1766 if o < validated.len() {
1767 return Err(ArrowError::InvalidArgumentError(format!(
1768 "Split UTF-8 codepoint at offset {o}"
1769 )));
1770 }
1771 return Err(ArrowError::InvalidArgumentError(format!(
1772 "Offset of {o} exceeds length of values {}",
1773 validated.len()
1774 )));
1775 }
1776 }
1777 Ok(())
1778 }
1779}
1780
1781pub type Utf8Type = GenericStringType<i32>;
1783pub type LargeUtf8Type = GenericStringType<i64>;
1785
1786pub struct GenericBinaryType<O: OffsetSizeTrait> {
1788 phantom: PhantomData<O>,
1789}
1790
1791impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1792 type Offset = O;
1793 type Native = [u8];
1794 const PREFIX: &'static str = "Binary";
1795
1796 const DATA_TYPE: DataType = if O::IS_LARGE {
1797 DataType::LargeBinary
1798 } else {
1799 DataType::Binary
1800 };
1801
1802 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1803 let max_offset = offsets.last().unwrap().as_usize();
1805 if values.len() < max_offset {
1806 return Err(ArrowError::InvalidArgumentError(format!(
1807 "Maximum offset of {max_offset} is larger than values of length {}",
1808 values.len()
1809 )));
1810 }
1811 Ok(())
1812 }
1813}
1814
1815pub type BinaryType = GenericBinaryType<i32>;
1817pub type LargeBinaryType = GenericBinaryType<i64>;
1819
1820mod byte_view {
1821 use crate::types::{BinaryViewType, StringViewType};
1822
1823 pub trait Sealed: Send + Sync {}
1824 impl Sealed for StringViewType {}
1825 impl Sealed for BinaryViewType {}
1826}
1827
1828pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1830 const IS_UTF8: bool;
1832
1833 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1835 DataType::Utf8View
1836 } else {
1837 DataType::BinaryView
1838 };
1839
1840 const PREFIX: &'static str;
1842
1843 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1847
1848 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1850
1851 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1853}
1854
1855#[derive(PartialEq)]
1857pub struct StringViewType {}
1858
1859impl ByteViewType for StringViewType {
1860 const IS_UTF8: bool = true;
1861 const PREFIX: &'static str = "String";
1862
1863 type Native = str;
1864 type Owned = String;
1865
1866 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1867 validate_string_view(views, buffers)
1868 }
1869}
1870
1871#[derive(PartialEq)]
1873pub struct BinaryViewType {}
1874
1875impl ByteViewType for BinaryViewType {
1876 const IS_UTF8: bool = false;
1877 const PREFIX: &'static str = "Binary";
1878 type Native = [u8];
1879 type Owned = Vec<u8>;
1880
1881 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1882 validate_binary_view(views, buffers)
1883 }
1884}
1885
1886#[cfg(test)]
1887mod tests {
1888 use super::*;
1889 use arrow_data::{BufferSpec, layout};
1890
1891 #[test]
1892 fn month_day_nano_should_roundtrip() {
1893 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1894 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1895 }
1896
1897 #[test]
1898 fn month_day_nano_should_roundtrip_neg() {
1899 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1900 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1901 }
1902
1903 #[test]
1904 fn day_time_should_roundtrip() {
1905 let value = IntervalDayTimeType::make_value(1, 2);
1906 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1907 }
1908
1909 #[test]
1910 fn day_time_should_roundtrip_neg() {
1911 let value = IntervalDayTimeType::make_value(-1, -2);
1912 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1913 }
1914
1915 #[test]
1916 fn year_month_should_roundtrip() {
1917 let value = IntervalYearMonthType::make_value(1, 2);
1918 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1919 }
1920
1921 #[test]
1922 fn year_month_should_roundtrip_neg() {
1923 let value = IntervalYearMonthType::make_value(-1, -2);
1924 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1925 }
1926
1927 fn test_layout<T: ArrowPrimitiveType>() {
1928 let layout = layout(&T::DATA_TYPE);
1929
1930 assert_eq!(layout.buffers.len(), 1);
1931
1932 let spec = &layout.buffers[0];
1933 assert_eq!(
1934 spec,
1935 &BufferSpec::FixedWidth {
1936 byte_width: std::mem::size_of::<T::Native>(),
1937 alignment: std::mem::align_of::<T::Native>(),
1938 }
1939 );
1940 }
1941
1942 #[test]
1943 fn test_layouts() {
1944 test_layout::<Int8Type>();
1945 test_layout::<Int16Type>();
1946 test_layout::<Int32Type>();
1947 test_layout::<Int64Type>();
1948 test_layout::<UInt8Type>();
1949 test_layout::<UInt16Type>();
1950 test_layout::<UInt32Type>();
1951 test_layout::<UInt64Type>();
1952 test_layout::<Float16Type>();
1953 test_layout::<Float32Type>();
1954 test_layout::<Float64Type>();
1955 test_layout::<Decimal32Type>();
1956 test_layout::<Decimal64Type>();
1957 test_layout::<Decimal128Type>();
1958 test_layout::<Decimal256Type>();
1959 test_layout::<TimestampNanosecondType>();
1960 test_layout::<TimestampMillisecondType>();
1961 test_layout::<TimestampMicrosecondType>();
1962 test_layout::<TimestampNanosecondType>();
1963 test_layout::<TimestampSecondType>();
1964 test_layout::<Date32Type>();
1965 test_layout::<Date64Type>();
1966 test_layout::<Time32SecondType>();
1967 test_layout::<Time32MillisecondType>();
1968 test_layout::<Time64MicrosecondType>();
1969 test_layout::<Time64NanosecondType>();
1970 test_layout::<IntervalMonthDayNanoType>();
1971 test_layout::<IntervalDayTimeType>();
1972 test_layout::<IntervalYearMonthType>();
1973 test_layout::<DurationNanosecondType>();
1974 test_layout::<DurationMicrosecondType>();
1975 test_layout::<DurationMillisecondType>();
1976 test_layout::<DurationSecondType>();
1977 }
1978}