1use crate::delta::{
8 add_days_datetime, add_months_date, add_months_datetime, sub_days_datetime, sub_months_datetime,
9};
10use crate::temporal_conversions::as_datetime_with_timezone;
11use crate::timezone::Tz;
12use crate::{ArrowNativeTypeOp, OffsetSizeTrait};
13use arrow_buffer::{Buffer, OffsetBuffer, i256};
14use arrow_data::decimal::{
15 DecimalNativeType, is_validate_decimal_precision, is_validate_decimal32_precision,
16 is_validate_decimal64_precision, is_validate_decimal256_precision, validate_decimal_precision,
17 validate_decimal32_precision, validate_decimal64_precision, validate_decimal256_precision,
18};
19use arrow_data::{validate_binary_view, validate_string_view};
20use arrow_schema::{
21 ArrowError, DECIMAL_DEFAULT_SCALE, DECIMAL32_DEFAULT_SCALE, DECIMAL32_MAX_PRECISION,
22 DECIMAL32_MAX_SCALE, DECIMAL64_DEFAULT_SCALE, DECIMAL64_MAX_PRECISION, DECIMAL64_MAX_SCALE,
23 DECIMAL128_MAX_PRECISION, DECIMAL128_MAX_SCALE, DECIMAL256_MAX_PRECISION, DECIMAL256_MAX_SCALE,
24 DataType, IntervalUnit, TimeUnit,
25};
26use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, TimeZone};
27use half::f16;
28use std::fmt::Debug;
29use std::marker::PhantomData;
30use std::ops::Sub;
31
32pub use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
34
35#[derive(Debug)]
39pub struct BooleanType {}
40
41impl BooleanType {
42 pub const DATA_TYPE: DataType = DataType::Boolean;
44}
45
46pub trait ArrowPrimitiveType: primitive::PrimitiveTypeSealed + 'static {
55 type Native: ArrowNativeTypeOp;
57
58 const DATA_TYPE: DataType;
60
61 fn default_value() -> Self::Native {
65 Default::default()
66 }
67}
68
69mod primitive {
70 pub trait PrimitiveTypeSealed {}
71}
72
73macro_rules! make_type {
74 ($name:ident, $native_ty:ty, $data_ty:expr, $doc_string: literal) => {
75 #[derive(Debug)]
76 #[doc = $doc_string]
77 pub struct $name {}
78
79 impl ArrowPrimitiveType for $name {
80 type Native = $native_ty;
81 const DATA_TYPE: DataType = $data_ty;
82 }
83
84 impl primitive::PrimitiveTypeSealed for $name {}
85 };
86}
87
88make_type!(Int8Type, i8, DataType::Int8, "A signed 8-bit integer type.");
89make_type!(
90 Int16Type,
91 i16,
92 DataType::Int16,
93 "Signed 16-bit integer type."
94);
95make_type!(
96 Int32Type,
97 i32,
98 DataType::Int32,
99 "Signed 32-bit integer type."
100);
101make_type!(
102 Int64Type,
103 i64,
104 DataType::Int64,
105 "Signed 64-bit integer type."
106);
107make_type!(
108 UInt8Type,
109 u8,
110 DataType::UInt8,
111 "Unsigned 8-bit integer type."
112);
113make_type!(
114 UInt16Type,
115 u16,
116 DataType::UInt16,
117 "Unsigned 16-bit integer type."
118);
119make_type!(
120 UInt32Type,
121 u32,
122 DataType::UInt32,
123 "Unsigned 32-bit integer type."
124);
125make_type!(
126 UInt64Type,
127 u64,
128 DataType::UInt64,
129 "Unsigned 64-bit integer type."
130);
131make_type!(
132 Float16Type,
133 f16,
134 DataType::Float16,
135 "16-bit floating point number type."
136);
137make_type!(
138 Float32Type,
139 f32,
140 DataType::Float32,
141 "32-bit floating point number type."
142);
143make_type!(
144 Float64Type,
145 f64,
146 DataType::Float64,
147 "64-bit floating point number type."
148);
149make_type!(
150 TimestampSecondType,
151 i64,
152 DataType::Timestamp(TimeUnit::Second, None),
153 "Timestamp second type with an optional timezone."
154);
155make_type!(
156 TimestampMillisecondType,
157 i64,
158 DataType::Timestamp(TimeUnit::Millisecond, None),
159 "Timestamp millisecond type with an optional timezone."
160);
161make_type!(
162 TimestampMicrosecondType,
163 i64,
164 DataType::Timestamp(TimeUnit::Microsecond, None),
165 "Timestamp microsecond type with an optional timezone."
166);
167make_type!(
168 TimestampNanosecondType,
169 i64,
170 DataType::Timestamp(TimeUnit::Nanosecond, None),
171 "Timestamp nanosecond type with an optional timezone."
172);
173make_type!(
174 Date32Type,
175 i32,
176 DataType::Date32,
177 "32-bit date type: the elapsed time since UNIX epoch in days (32 bits)."
178);
179make_type!(
180 Date64Type,
181 i64,
182 DataType::Date64,
183 "64-bit date type: the elapsed time since UNIX epoch in milliseconds (64 bits). \
184 Values must be divisible by `86_400_000`. \
185 See [`DataType::Date64`] for more details."
186);
187make_type!(
188 Time32SecondType,
189 i32,
190 DataType::Time32(TimeUnit::Second),
191 "32-bit time type: the elapsed time since midnight in seconds."
192);
193make_type!(
194 Time32MillisecondType,
195 i32,
196 DataType::Time32(TimeUnit::Millisecond),
197 "32-bit time type: the elapsed time since midnight in milliseconds."
198);
199make_type!(
200 Time64MicrosecondType,
201 i64,
202 DataType::Time64(TimeUnit::Microsecond),
203 "64-bit time type: the elapsed time since midnight in microseconds."
204);
205make_type!(
206 Time64NanosecondType,
207 i64,
208 DataType::Time64(TimeUnit::Nanosecond),
209 "64-bit time type: the elapsed time since midnight in nanoseconds."
210);
211make_type!(
212 IntervalYearMonthType,
213 i32,
214 DataType::Interval(IntervalUnit::YearMonth),
215 "32-bit “calendar” interval type: the number of whole months."
216);
217make_type!(
218 IntervalDayTimeType,
219 IntervalDayTime,
220 DataType::Interval(IntervalUnit::DayTime),
221 "“Calendar” interval type: days and milliseconds. See [`IntervalDayTime`] for more details."
222);
223make_type!(
224 IntervalMonthDayNanoType,
225 IntervalMonthDayNano,
226 DataType::Interval(IntervalUnit::MonthDayNano),
227 r"“Calendar” interval type: months, days, and nanoseconds. See [`IntervalMonthDayNano`] for more details."
228);
229make_type!(
230 DurationSecondType,
231 i64,
232 DataType::Duration(TimeUnit::Second),
233 "Elapsed time type: seconds."
234);
235make_type!(
236 DurationMillisecondType,
237 i64,
238 DataType::Duration(TimeUnit::Millisecond),
239 "Elapsed time type: milliseconds."
240);
241make_type!(
242 DurationMicrosecondType,
243 i64,
244 DataType::Duration(TimeUnit::Microsecond),
245 "Elapsed time type: microseconds."
246);
247make_type!(
248 DurationNanosecondType,
249 i64,
250 DataType::Duration(TimeUnit::Nanosecond),
251 "Elapsed time type: nanoseconds."
252);
253
254pub trait ArrowDictionaryKeyType: ArrowPrimitiveType {}
257
258impl ArrowDictionaryKeyType for Int8Type {}
259
260impl ArrowDictionaryKeyType for Int16Type {}
261
262impl ArrowDictionaryKeyType for Int32Type {}
263
264impl ArrowDictionaryKeyType for Int64Type {}
265
266impl ArrowDictionaryKeyType for UInt8Type {}
267
268impl ArrowDictionaryKeyType for UInt16Type {}
269
270impl ArrowDictionaryKeyType for UInt32Type {}
271
272impl ArrowDictionaryKeyType for UInt64Type {}
273
274pub trait RunEndIndexType: ArrowPrimitiveType {}
278
279impl RunEndIndexType for Int16Type {}
280
281impl RunEndIndexType for Int32Type {}
282
283impl RunEndIndexType for Int64Type {}
284
285pub trait ArrowTemporalType: ArrowPrimitiveType {}
287
288impl ArrowTemporalType for TimestampSecondType {}
289impl ArrowTemporalType for TimestampMillisecondType {}
290impl ArrowTemporalType for TimestampMicrosecondType {}
291impl ArrowTemporalType for TimestampNanosecondType {}
292impl ArrowTemporalType for Date32Type {}
293impl ArrowTemporalType for Date64Type {}
294impl ArrowTemporalType for Time32SecondType {}
295impl ArrowTemporalType for Time32MillisecondType {}
296impl ArrowTemporalType for Time64MicrosecondType {}
297impl ArrowTemporalType for Time64NanosecondType {}
298impl ArrowTemporalType for DurationSecondType {}
302impl ArrowTemporalType for DurationMillisecondType {}
303impl ArrowTemporalType for DurationMicrosecondType {}
304impl ArrowTemporalType for DurationNanosecondType {}
305
306pub trait ArrowTimestampType: ArrowTemporalType<Native = i64> {
308 const UNIT: TimeUnit;
310
311 #[deprecated(since = "58.1.0", note = "Use from_naive_datetime instead")]
315 fn make_value(naive: NaiveDateTime) -> Option<i64>;
316
317 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64>;
326
327 fn from_naive_datetime(naive: NaiveDateTime, tz: Option<&Tz>) -> Option<i64> {
335 match tz {
336 Some(tz) => match tz.from_local_datetime(&naive) {
337 chrono::offset::LocalResult::Single(dt) => Self::from_datetime(dt),
338 chrono::offset::LocalResult::Ambiguous(dt1, _) => Self::from_datetime(dt1),
339 chrono::offset::LocalResult::None => None,
340 },
341 None => Self::from_datetime(naive.and_utc()),
342 }
343 }
344}
345
346impl ArrowTimestampType for TimestampSecondType {
347 const UNIT: TimeUnit = TimeUnit::Second;
348
349 fn make_value(naive: NaiveDateTime) -> Option<i64> {
350 Some(naive.and_utc().timestamp())
351 }
352
353 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
354 Some(datetime.timestamp())
355 }
356}
357impl ArrowTimestampType for TimestampMillisecondType {
358 const UNIT: TimeUnit = TimeUnit::Millisecond;
359
360 fn make_value(naive: NaiveDateTime) -> Option<i64> {
361 let utc = naive.and_utc();
362 let millis = utc.timestamp().checked_mul(1_000)?;
363 millis.checked_add(utc.timestamp_subsec_millis() as i64)
364 }
365
366 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
367 let millis = datetime.timestamp().checked_mul(1_000)?;
368 millis.checked_add(datetime.timestamp_subsec_millis() as i64)
369 }
370}
371impl ArrowTimestampType for TimestampMicrosecondType {
372 const UNIT: TimeUnit = TimeUnit::Microsecond;
373
374 fn make_value(naive: NaiveDateTime) -> Option<i64> {
375 let utc = naive.and_utc();
376 let micros = utc.timestamp().checked_mul(1_000_000)?;
377 micros.checked_add(utc.timestamp_subsec_micros() as i64)
378 }
379
380 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
381 let micros = datetime.timestamp().checked_mul(1_000_000)?;
382 micros.checked_add(datetime.timestamp_subsec_micros() as i64)
383 }
384}
385impl ArrowTimestampType for TimestampNanosecondType {
386 const UNIT: TimeUnit = TimeUnit::Nanosecond;
387
388 fn make_value(naive: NaiveDateTime) -> Option<i64> {
389 let utc = naive.and_utc();
390 let nanos = utc.timestamp().checked_mul(1_000_000_000)?;
391 nanos.checked_add(utc.timestamp_subsec_nanos() as i64)
392 }
393
394 fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<i64> {
395 datetime.timestamp_nanos_opt()
396 }
397}
398
399fn add_year_months<T: ArrowTimestampType>(
400 timestamp: <T as ArrowPrimitiveType>::Native,
401 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
402 tz: Tz,
403) -> Option<<T as ArrowPrimitiveType>::Native> {
404 let months = IntervalYearMonthType::to_months(delta);
405 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
406 let res = add_months_datetime(res, months)?;
407 T::from_naive_datetime(res.naive_utc(), None)
408}
409
410fn add_day_time<T: ArrowTimestampType>(
411 timestamp: <T as ArrowPrimitiveType>::Native,
412 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
413 tz: Tz,
414) -> Option<<T as ArrowPrimitiveType>::Native> {
415 let (days, ms) = IntervalDayTimeType::to_parts(delta);
416 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
417 let res = add_days_datetime(res, days)?;
418 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
419 T::from_naive_datetime(res.naive_utc(), None)
420}
421
422fn add_month_day_nano<T: ArrowTimestampType>(
423 timestamp: <T as ArrowPrimitiveType>::Native,
424 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
425 tz: Tz,
426) -> Option<<T as ArrowPrimitiveType>::Native> {
427 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
428 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
429 let res = add_months_datetime(res, months)?;
430 let res = add_days_datetime(res, days)?;
431 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
432 T::from_naive_datetime(res.naive_utc(), None)
433}
434
435fn subtract_year_months<T: ArrowTimestampType>(
436 timestamp: <T as ArrowPrimitiveType>::Native,
437 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
438 tz: Tz,
439) -> Option<<T as ArrowPrimitiveType>::Native> {
440 let months = IntervalYearMonthType::to_months(delta);
441 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
442 let res = sub_months_datetime(res, months)?;
443 T::from_naive_datetime(res.naive_utc(), None)
444}
445
446fn subtract_day_time<T: ArrowTimestampType>(
447 timestamp: <T as ArrowPrimitiveType>::Native,
448 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
449 tz: Tz,
450) -> Option<<T as ArrowPrimitiveType>::Native> {
451 let (days, ms) = IntervalDayTimeType::to_parts(delta);
452 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
453 let res = sub_days_datetime(res, days)?;
454 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
455 T::from_naive_datetime(res.naive_utc(), None)
456}
457
458fn subtract_month_day_nano<T: ArrowTimestampType>(
459 timestamp: <T as ArrowPrimitiveType>::Native,
460 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
461 tz: Tz,
462) -> Option<<T as ArrowPrimitiveType>::Native> {
463 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
464 let res = as_datetime_with_timezone::<T>(timestamp, tz)?;
465 let res = sub_months_datetime(res, months)?;
466 let res = sub_days_datetime(res, days)?;
467 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
468 T::from_naive_datetime(res.naive_utc(), None)
469}
470
471impl TimestampSecondType {
472 pub fn add_year_months(
482 timestamp: <Self as ArrowPrimitiveType>::Native,
483 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
484 tz: Tz,
485 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
486 add_year_months::<Self>(timestamp, delta, tz)
487 }
488
489 pub fn add_day_time(
499 timestamp: <Self as ArrowPrimitiveType>::Native,
500 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
501 tz: Tz,
502 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
503 add_day_time::<Self>(timestamp, delta, tz)
504 }
505
506 pub fn add_month_day_nano(
515 timestamp: <Self as ArrowPrimitiveType>::Native,
516 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
517 tz: Tz,
518 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
519 add_month_day_nano::<Self>(timestamp, delta, tz)
520 }
521
522 pub fn subtract_year_months(
532 timestamp: <Self as ArrowPrimitiveType>::Native,
533 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
534 tz: Tz,
535 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
536 subtract_year_months::<Self>(timestamp, delta, tz)
537 }
538
539 pub fn subtract_day_time(
549 timestamp: <Self as ArrowPrimitiveType>::Native,
550 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
551 tz: Tz,
552 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
553 subtract_day_time::<Self>(timestamp, delta, tz)
554 }
555
556 pub fn subtract_month_day_nano(
566 timestamp: <Self as ArrowPrimitiveType>::Native,
567 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
568 tz: Tz,
569 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
570 subtract_month_day_nano::<Self>(timestamp, delta, tz)
571 }
572}
573
574impl TimestampMicrosecondType {
575 pub fn add_year_months(
583 timestamp: <Self as ArrowPrimitiveType>::Native,
584 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
585 tz: Tz,
586 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
587 add_year_months::<Self>(timestamp, delta, tz)
588 }
589
590 pub fn add_day_time(
598 timestamp: <Self as ArrowPrimitiveType>::Native,
599 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
600 tz: Tz,
601 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
602 add_day_time::<Self>(timestamp, delta, tz)
603 }
604
605 pub fn add_month_day_nano(
613 timestamp: <Self as ArrowPrimitiveType>::Native,
614 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
615 tz: Tz,
616 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
617 add_month_day_nano::<Self>(timestamp, delta, tz)
618 }
619
620 pub fn subtract_year_months(
628 timestamp: <Self as ArrowPrimitiveType>::Native,
629 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
630 tz: Tz,
631 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
632 subtract_year_months::<Self>(timestamp, delta, tz)
633 }
634
635 pub fn subtract_day_time(
643 timestamp: <Self as ArrowPrimitiveType>::Native,
644 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
645 tz: Tz,
646 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
647 subtract_day_time::<Self>(timestamp, delta, tz)
648 }
649
650 pub fn subtract_month_day_nano(
658 timestamp: <Self as ArrowPrimitiveType>::Native,
659 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
660 tz: Tz,
661 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
662 subtract_month_day_nano::<Self>(timestamp, delta, tz)
663 }
664}
665
666impl TimestampMillisecondType {
667 pub fn add_year_months(
675 timestamp: <Self as ArrowPrimitiveType>::Native,
676 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
677 tz: Tz,
678 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
679 add_year_months::<Self>(timestamp, delta, tz)
680 }
681
682 pub fn add_day_time(
690 timestamp: <Self as ArrowPrimitiveType>::Native,
691 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
692 tz: Tz,
693 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
694 add_day_time::<Self>(timestamp, delta, tz)
695 }
696
697 pub fn add_month_day_nano(
705 timestamp: <Self as ArrowPrimitiveType>::Native,
706 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
707 tz: Tz,
708 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
709 add_month_day_nano::<Self>(timestamp, delta, tz)
710 }
711
712 pub fn subtract_year_months(
720 timestamp: <Self as ArrowPrimitiveType>::Native,
721 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
722 tz: Tz,
723 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
724 subtract_year_months::<Self>(timestamp, delta, tz)
725 }
726
727 pub fn subtract_day_time(
735 timestamp: <Self as ArrowPrimitiveType>::Native,
736 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
737 tz: Tz,
738 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
739 subtract_day_time::<Self>(timestamp, delta, tz)
740 }
741
742 pub fn subtract_month_day_nano(
750 timestamp: <Self as ArrowPrimitiveType>::Native,
751 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
752 tz: Tz,
753 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
754 subtract_month_day_nano::<Self>(timestamp, delta, tz)
755 }
756}
757
758impl TimestampNanosecondType {
759 pub fn add_year_months(
767 timestamp: <Self as ArrowPrimitiveType>::Native,
768 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
769 tz: Tz,
770 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
771 add_year_months::<Self>(timestamp, delta, tz)
772 }
773
774 pub fn add_day_time(
782 timestamp: <Self as ArrowPrimitiveType>::Native,
783 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
784 tz: Tz,
785 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
786 add_day_time::<Self>(timestamp, delta, tz)
787 }
788
789 pub fn add_month_day_nano(
797 timestamp: <Self as ArrowPrimitiveType>::Native,
798 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
799 tz: Tz,
800 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
801 add_month_day_nano::<Self>(timestamp, delta, tz)
802 }
803
804 pub fn subtract_year_months(
812 timestamp: <Self as ArrowPrimitiveType>::Native,
813 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
814 tz: Tz,
815 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
816 subtract_year_months::<Self>(timestamp, delta, tz)
817 }
818
819 pub fn subtract_day_time(
827 timestamp: <Self as ArrowPrimitiveType>::Native,
828 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
829 tz: Tz,
830 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
831 subtract_day_time::<Self>(timestamp, delta, tz)
832 }
833
834 pub fn subtract_month_day_nano(
842 timestamp: <Self as ArrowPrimitiveType>::Native,
843 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
844 tz: Tz,
845 ) -> Option<<Self as ArrowPrimitiveType>::Native> {
846 subtract_month_day_nano::<Self>(timestamp, delta, tz)
847 }
848}
849
850impl IntervalYearMonthType {
851 #[inline]
858 pub fn make_value(
859 years: i32,
860 months: i32,
861 ) -> <IntervalYearMonthType as ArrowPrimitiveType>::Native {
862 years * 12 + months
863 }
864
865 #[inline]
873 pub fn to_months(i: <IntervalYearMonthType as ArrowPrimitiveType>::Native) -> i32 {
874 i
875 }
876}
877
878impl IntervalDayTimeType {
879 #[inline]
886 pub fn make_value(days: i32, milliseconds: i32) -> IntervalDayTime {
887 IntervalDayTime { days, milliseconds }
888 }
889
890 #[inline]
896 pub fn to_parts(i: IntervalDayTime) -> (i32, i32) {
897 (i.days, i.milliseconds)
898 }
899}
900
901impl IntervalMonthDayNanoType {
902 #[inline]
910 pub fn make_value(months: i32, days: i32, nanoseconds: i64) -> IntervalMonthDayNano {
911 IntervalMonthDayNano {
912 months,
913 days,
914 nanoseconds,
915 }
916 }
917
918 #[inline]
924 pub fn to_parts(i: IntervalMonthDayNano) -> (i32, i32, i64) {
925 (i.months, i.days, i.nanoseconds)
926 }
927}
928
929impl Date32Type {
930 #[deprecated(since = "58.0.0", note = "Use to_naive_date_opt instead.")]
940 pub fn to_naive_date(i: <Date32Type as ArrowPrimitiveType>::Native) -> NaiveDate {
941 Self::to_naive_date_opt(i)
942 .unwrap_or_else(|| panic!("Date32Type::to_naive_date overflowed for date: {i}"))
943 }
944
945 pub fn to_naive_date_opt(i: <Date32Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
953 let epoch = NaiveDate::default();
954 let d = Duration::try_days(i as i64)?;
955 epoch.checked_add_signed(d)
956 }
957
958 pub fn from_naive_date(d: NaiveDate) -> <Date32Type as ArrowPrimitiveType>::Native {
964 let epoch = NaiveDate::default();
965 d.sub(epoch).num_days() as <Date32Type as ArrowPrimitiveType>::Native
966 }
967
968 #[deprecated(
979 since = "58.0.0",
980 note = "Use `add_year_months_opt` instead, which returns an Option to handle overflow."
981 )]
982 pub fn add_year_months(
983 date: <Date32Type as ArrowPrimitiveType>::Native,
984 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
985 ) -> <Date32Type as ArrowPrimitiveType>::Native {
986 Self::add_year_months_opt(date, delta).unwrap_or_else(|| {
987 panic!("Date32Type::add_year_months overflowed for date: {date}, delta: {delta}")
988 })
989 }
990
991 pub fn add_year_months_opt(
1000 date: <Date32Type as ArrowPrimitiveType>::Native,
1001 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1002 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1003 let prior = Date32Type::to_naive_date_opt(date)?;
1004 let months = IntervalYearMonthType::to_months(delta);
1005 let posterior = add_months_date(prior, months)?;
1006 Some(Date32Type::from_naive_date(posterior))
1007 }
1008
1009 #[deprecated(
1020 since = "58.0.0",
1021 note = "Use `add_day_time_opt` instead, which returns an Option to handle overflow."
1022 )]
1023 pub fn add_day_time(
1024 date: <Date32Type as ArrowPrimitiveType>::Native,
1025 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1026 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1027 Self::add_day_time_opt(date, delta).unwrap_or_else(|| {
1028 panic!("Date32Type::add_day_time overflowed for date: {date}, delta: {delta:?}")
1029 })
1030 }
1031
1032 pub fn add_day_time_opt(
1041 date: <Date32Type as ArrowPrimitiveType>::Native,
1042 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1043 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1044 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1045 let res = Date32Type::to_naive_date_opt(date)?;
1046 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1047 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1048 Some(Date32Type::from_naive_date(res))
1049 }
1050
1051 #[deprecated(
1062 since = "58.0.0",
1063 note = "Use `add_month_day_nano_opt` instead, which returns an Option to handle overflow."
1064 )]
1065 pub fn add_month_day_nano(
1066 date: <Date32Type as ArrowPrimitiveType>::Native,
1067 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1068 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1069 Self::add_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1070 panic!("Date32Type::add_month_day_nano overflowed for date: {date}, delta: {delta:?}")
1071 })
1072 }
1073
1074 pub fn add_month_day_nano_opt(
1083 date: <Date32Type as ArrowPrimitiveType>::Native,
1084 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1085 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1086 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1087 let res = Date32Type::to_naive_date_opt(date)?;
1088 let res = add_months_date(res, months)?;
1089 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1090 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1091 Some(Date32Type::from_naive_date(res))
1092 }
1093
1094 #[deprecated(
1105 since = "58.0.0",
1106 note = "Use `subtract_year_months_opt` instead, which returns an Option to handle overflow."
1107 )]
1108 pub fn subtract_year_months(
1109 date: <Date32Type as ArrowPrimitiveType>::Native,
1110 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1111 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1112 Self::subtract_year_months_opt(date, delta).unwrap_or_else(|| {
1113 panic!("Date32Type::subtract_year_months overflowed for date: {date}, delta: {delta}")
1114 })
1115 }
1116
1117 pub fn subtract_year_months_opt(
1126 date: <Date32Type as ArrowPrimitiveType>::Native,
1127 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1128 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1129 let prior = Date32Type::to_naive_date_opt(date)?;
1130 let months = IntervalYearMonthType::to_months(delta.checked_neg()?);
1133 let posterior = add_months_date(prior, months)?;
1134 Some(Date32Type::from_naive_date(posterior))
1135 }
1136
1137 #[deprecated(
1148 since = "58.0.0",
1149 note = "Use `subtract_day_time_opt` instead, which returns an Option to handle overflow."
1150 )]
1151 pub fn subtract_day_time(
1152 date: <Date32Type as ArrowPrimitiveType>::Native,
1153 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1154 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1155 Self::subtract_day_time_opt(date, delta).unwrap_or_else(|| {
1156 panic!("Date32Type::subtract_day_time overflowed for date: {date}, delta: {delta:?}")
1157 })
1158 }
1159
1160 pub fn subtract_day_time_opt(
1169 date: <Date32Type as ArrowPrimitiveType>::Native,
1170 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1171 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1172 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1173 let res = Date32Type::to_naive_date_opt(date)?;
1174 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1175 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1176 Some(Date32Type::from_naive_date(res))
1177 }
1178
1179 #[deprecated(
1190 since = "58.0.0",
1191 note = "Use `subtract_month_day_nano_opt` instead, which returns an Option to handle overflow."
1192 )]
1193 pub fn subtract_month_day_nano(
1194 date: <Date32Type as ArrowPrimitiveType>::Native,
1195 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1196 ) -> <Date32Type as ArrowPrimitiveType>::Native {
1197 Self::subtract_month_day_nano_opt(date, delta).unwrap_or_else(|| {
1198 panic!(
1199 "Date32Type::subtract_month_day_nano overflowed for date: {date}, delta: {delta:?}",
1200 )
1201 })
1202 }
1203
1204 pub fn subtract_month_day_nano_opt(
1213 date: <Date32Type as ArrowPrimitiveType>::Native,
1214 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1215 ) -> Option<<Date32Type as ArrowPrimitiveType>::Native> {
1216 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1217 let res = Date32Type::to_naive_date_opt(date)?;
1218 let res = add_months_date(res, months.checked_neg()?)?;
1221 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1222 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1223 Some(Date32Type::from_naive_date(res))
1224 }
1225}
1226
1227impl Date64Type {
1228 pub fn to_naive_date_opt(i: <Date64Type as ArrowPrimitiveType>::Native) -> Option<NaiveDate> {
1239 let epoch = NaiveDate::default();
1240 let d = Duration::try_milliseconds(i)?;
1241 epoch.checked_add_signed(d)
1242 }
1243
1244 pub fn from_naive_date(d: NaiveDate) -> <Date64Type as ArrowPrimitiveType>::Native {
1250 let epoch = NaiveDate::default();
1251 d.sub(epoch).num_milliseconds()
1252 }
1253
1254 pub fn add_year_months_opt(
1263 date: <Date64Type as ArrowPrimitiveType>::Native,
1264 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1265 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1266 let prior = Date64Type::to_naive_date_opt(date)?;
1267 let months = IntervalYearMonthType::to_months(delta);
1268 let posterior = add_months_date(prior, months)?;
1269 Some(Date64Type::from_naive_date(posterior))
1270 }
1271
1272 pub fn add_day_time_opt(
1281 date: <Date64Type as ArrowPrimitiveType>::Native,
1282 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1283 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1284 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1285 let res = Date64Type::to_naive_date_opt(date)?;
1286 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1287 let res = res.checked_add_signed(Duration::try_milliseconds(ms as i64)?)?;
1288 Some(Date64Type::from_naive_date(res))
1289 }
1290
1291 pub fn add_month_day_nano_opt(
1300 date: <Date64Type as ArrowPrimitiveType>::Native,
1301 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1302 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1303 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1304 let res = Date64Type::to_naive_date_opt(date)?;
1305 let res = add_months_date(res, months)?;
1306 let res = res.checked_add_signed(Duration::try_days(days as i64)?)?;
1307 let res = res.checked_add_signed(Duration::nanoseconds(nanos))?;
1308 Some(Date64Type::from_naive_date(res))
1309 }
1310
1311 pub fn subtract_year_months_opt(
1320 date: <Date64Type as ArrowPrimitiveType>::Native,
1321 delta: <IntervalYearMonthType as ArrowPrimitiveType>::Native,
1322 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1323 let prior = Date64Type::to_naive_date_opt(date)?;
1324 let months = IntervalYearMonthType::to_months(delta.checked_neg()?);
1327 let posterior = add_months_date(prior, months)?;
1328 Some(Date64Type::from_naive_date(posterior))
1329 }
1330
1331 pub fn subtract_day_time_opt(
1340 date: <Date64Type as ArrowPrimitiveType>::Native,
1341 delta: <IntervalDayTimeType as ArrowPrimitiveType>::Native,
1342 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1343 let (days, ms) = IntervalDayTimeType::to_parts(delta);
1344 let res = Date64Type::to_naive_date_opt(date)?;
1345 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1346 let res = res.checked_sub_signed(Duration::try_milliseconds(ms as i64)?)?;
1347 Some(Date64Type::from_naive_date(res))
1348 }
1349
1350 pub fn subtract_month_day_nano_opt(
1359 date: <Date64Type as ArrowPrimitiveType>::Native,
1360 delta: <IntervalMonthDayNanoType as ArrowPrimitiveType>::Native,
1361 ) -> Option<<Date64Type as ArrowPrimitiveType>::Native> {
1362 let (months, days, nanos) = IntervalMonthDayNanoType::to_parts(delta);
1363 let res = Date64Type::to_naive_date_opt(date)?;
1364 let res = add_months_date(res, months.checked_neg()?)?;
1367 let res = res.checked_sub_signed(Duration::try_days(days as i64)?)?;
1368 let res = res.checked_sub_signed(Duration::nanoseconds(nanos))?;
1369 Some(Date64Type::from_naive_date(res))
1370 }
1371}
1372
1373mod decimal {
1377 use super::*;
1378
1379 pub trait DecimalTypeSealed {}
1380 impl DecimalTypeSealed for Decimal32Type {}
1381 impl DecimalTypeSealed for Decimal64Type {}
1382 impl DecimalTypeSealed for Decimal128Type {}
1383 impl DecimalTypeSealed for Decimal256Type {}
1384}
1385
1386pub trait DecimalType:
1398 'static + Send + Sync + ArrowPrimitiveType<Native: DecimalNativeType> + decimal::DecimalTypeSealed
1399{
1400 const BYTE_LENGTH: usize;
1402 const MAX_PRECISION: u8;
1404 const MAX_SCALE: i8;
1406 const MAX_FOR_EACH_PRECISION: &'static [Self::Native];
1408 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType;
1410 const DEFAULT_TYPE: DataType;
1412
1413 const PREFIX: &'static str;
1415
1416 fn format_decimal(value: Self::Native, _precision: u8, scale: i8) -> String {
1420 arrow_data::decimal::format_decimal(value, scale)
1421 }
1422
1423 fn validate_decimal_precision(
1425 value: Self::Native,
1426 precision: u8,
1427 scale: i8,
1428 ) -> Result<(), ArrowError>;
1429
1430 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool;
1432}
1433
1434pub fn validate_decimal_precision_and_scale<T: DecimalType>(
1442 precision: u8,
1443 scale: i8,
1444) -> Result<(), ArrowError> {
1445 if precision == 0 {
1446 return Err(ArrowError::InvalidArgumentError(format!(
1447 "precision cannot be 0, has to be between [1, {}]",
1448 T::MAX_PRECISION
1449 )));
1450 }
1451 if precision > T::MAX_PRECISION {
1452 return Err(ArrowError::InvalidArgumentError(format!(
1453 "precision {} is greater than max {}",
1454 precision,
1455 T::MAX_PRECISION
1456 )));
1457 }
1458 if scale > T::MAX_SCALE {
1459 return Err(ArrowError::InvalidArgumentError(format!(
1460 "scale {} is greater than max {}",
1461 scale,
1462 T::MAX_SCALE
1463 )));
1464 }
1465 if scale > 0 && scale as u8 > precision {
1466 return Err(ArrowError::InvalidArgumentError(format!(
1467 "scale {scale} is greater than precision {precision}"
1468 )));
1469 }
1470
1471 Ok(())
1472}
1473
1474#[derive(Debug)]
1476pub struct Decimal32Type {}
1477
1478impl DecimalType for Decimal32Type {
1479 const BYTE_LENGTH: usize = 4;
1480 const MAX_PRECISION: u8 = DECIMAL32_MAX_PRECISION;
1481 const MAX_SCALE: i8 = DECIMAL32_MAX_SCALE;
1482 const MAX_FOR_EACH_PRECISION: &'static [i32] =
1483 &arrow_data::decimal::MAX_DECIMAL32_FOR_EACH_PRECISION;
1484 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal32;
1485 const DEFAULT_TYPE: DataType =
1486 DataType::Decimal32(DECIMAL32_MAX_PRECISION, DECIMAL32_DEFAULT_SCALE);
1487 const PREFIX: &'static str = "Decimal32";
1488
1489 fn validate_decimal_precision(num: i32, precision: u8, scale: i8) -> Result<(), ArrowError> {
1490 validate_decimal32_precision(num, precision, scale)
1491 }
1492
1493 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1494 is_validate_decimal32_precision(value, precision)
1495 }
1496}
1497
1498impl ArrowPrimitiveType for Decimal32Type {
1499 type Native = i32;
1500
1501 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1502}
1503
1504impl primitive::PrimitiveTypeSealed for Decimal32Type {}
1505
1506#[derive(Debug)]
1508pub struct Decimal64Type {}
1509
1510impl DecimalType for Decimal64Type {
1511 const BYTE_LENGTH: usize = 8;
1512 const MAX_PRECISION: u8 = DECIMAL64_MAX_PRECISION;
1513 const MAX_SCALE: i8 = DECIMAL64_MAX_SCALE;
1514 const MAX_FOR_EACH_PRECISION: &'static [i64] =
1515 &arrow_data::decimal::MAX_DECIMAL64_FOR_EACH_PRECISION;
1516 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal64;
1517 const DEFAULT_TYPE: DataType =
1518 DataType::Decimal64(DECIMAL64_MAX_PRECISION, DECIMAL64_DEFAULT_SCALE);
1519 const PREFIX: &'static str = "Decimal64";
1520
1521 fn validate_decimal_precision(num: i64, precision: u8, scale: i8) -> Result<(), ArrowError> {
1522 validate_decimal64_precision(num, precision, scale)
1523 }
1524
1525 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1526 is_validate_decimal64_precision(value, precision)
1527 }
1528}
1529
1530impl ArrowPrimitiveType for Decimal64Type {
1531 type Native = i64;
1532
1533 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1534}
1535
1536impl primitive::PrimitiveTypeSealed for Decimal64Type {}
1537
1538#[derive(Debug)]
1540pub struct Decimal128Type {}
1541
1542impl DecimalType for Decimal128Type {
1543 const BYTE_LENGTH: usize = 16;
1544 const MAX_PRECISION: u8 = DECIMAL128_MAX_PRECISION;
1545 const MAX_SCALE: i8 = DECIMAL128_MAX_SCALE;
1546 const MAX_FOR_EACH_PRECISION: &'static [i128] =
1547 &arrow_data::decimal::MAX_DECIMAL128_FOR_EACH_PRECISION;
1548 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal128;
1549 const DEFAULT_TYPE: DataType =
1550 DataType::Decimal128(DECIMAL128_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1551 const PREFIX: &'static str = "Decimal128";
1552
1553 fn validate_decimal_precision(num: i128, precision: u8, scale: i8) -> Result<(), ArrowError> {
1554 validate_decimal_precision(num, precision, scale)
1555 }
1556
1557 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1558 is_validate_decimal_precision(value, precision)
1559 }
1560}
1561
1562impl ArrowPrimitiveType for Decimal128Type {
1563 type Native = i128;
1564
1565 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1566}
1567
1568impl primitive::PrimitiveTypeSealed for Decimal128Type {}
1569
1570#[derive(Debug)]
1572pub struct Decimal256Type {}
1573
1574impl DecimalType for Decimal256Type {
1575 const BYTE_LENGTH: usize = 32;
1576 const MAX_PRECISION: u8 = DECIMAL256_MAX_PRECISION;
1577 const MAX_SCALE: i8 = DECIMAL256_MAX_SCALE;
1578 const MAX_FOR_EACH_PRECISION: &'static [i256] =
1579 &arrow_data::decimal::MAX_DECIMAL256_FOR_EACH_PRECISION;
1580 const TYPE_CONSTRUCTOR: fn(u8, i8) -> DataType = DataType::Decimal256;
1581 const DEFAULT_TYPE: DataType =
1582 DataType::Decimal256(DECIMAL256_MAX_PRECISION, DECIMAL_DEFAULT_SCALE);
1583 const PREFIX: &'static str = "Decimal256";
1584
1585 fn validate_decimal_precision(num: i256, precision: u8, scale: i8) -> Result<(), ArrowError> {
1586 validate_decimal256_precision(num, precision, scale)
1587 }
1588
1589 fn is_valid_decimal_precision(value: Self::Native, precision: u8) -> bool {
1590 is_validate_decimal256_precision(value, precision)
1591 }
1592}
1593
1594impl ArrowPrimitiveType for Decimal256Type {
1595 type Native = i256;
1596
1597 const DATA_TYPE: DataType = <Self as DecimalType>::DEFAULT_TYPE;
1598}
1599
1600impl primitive::PrimitiveTypeSealed for Decimal256Type {}
1601
1602pub(crate) mod bytes {
1606 use super::*;
1607
1608 pub trait ByteArrayTypeSealed {}
1609 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericStringType<O> {}
1610 impl<O: OffsetSizeTrait> ByteArrayTypeSealed for GenericBinaryType<O> {}
1611
1612 pub trait ByteArrayNativeType: std::fmt::Debug + Send + Sync {
1613 fn from_bytes_checked(b: &[u8]) -> Option<&Self>;
1614
1615 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self;
1619 }
1620
1621 impl ByteArrayNativeType for [u8] {
1622 #[inline]
1623 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1624 Some(b)
1625 }
1626
1627 #[inline]
1628 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1629 b
1630 }
1631 }
1632
1633 impl ByteArrayNativeType for str {
1634 #[inline]
1635 fn from_bytes_checked(b: &[u8]) -> Option<&Self> {
1636 std::str::from_utf8(b).ok()
1637 }
1638
1639 #[inline]
1640 unsafe fn from_bytes_unchecked(b: &[u8]) -> &Self {
1641 unsafe { std::str::from_utf8_unchecked(b) }
1642 }
1643 }
1644}
1645
1646pub trait ByteArrayType: 'static + Send + Sync + bytes::ByteArrayTypeSealed {
1650 type Offset: OffsetSizeTrait;
1652 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1656
1657 const PREFIX: &'static str;
1659
1660 const DATA_TYPE: DataType;
1662
1663 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError>;
1665}
1666
1667pub struct GenericStringType<O: OffsetSizeTrait> {
1669 phantom: PhantomData<O>,
1670}
1671
1672impl<O: OffsetSizeTrait> ByteArrayType for GenericStringType<O> {
1673 type Offset = O;
1674 type Native = str;
1675 const PREFIX: &'static str = "String";
1676
1677 const DATA_TYPE: DataType = if O::IS_LARGE {
1678 DataType::LargeUtf8
1679 } else {
1680 DataType::Utf8
1681 };
1682
1683 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1684 let start = offsets.first().as_usize();
1685 let end = offsets.last().as_usize();
1686 if end > values.len() {
1687 return Err(ArrowError::InvalidArgumentError(format!(
1688 "Offset of {end} exceeds length of values {}",
1689 values.len()
1690 )));
1691 }
1692
1693 let validated = std::str::from_utf8(&values[start..end]).map_err(|e| {
1695 ArrowError::InvalidArgumentError(format!("Encountered non UTF-8 data: {e}"))
1696 })?;
1697
1698 for offset in offsets.iter() {
1700 let o = offset.as_usize();
1701 if !validated.is_char_boundary(o - start) {
1702 return Err(ArrowError::InvalidArgumentError(format!(
1703 "Split UTF-8 codepoint at offset {o}"
1704 )));
1705 }
1706 }
1707 Ok(())
1708 }
1709}
1710
1711pub type Utf8Type = GenericStringType<i32>;
1713pub type LargeUtf8Type = GenericStringType<i64>;
1715
1716pub struct GenericBinaryType<O: OffsetSizeTrait> {
1718 phantom: PhantomData<O>,
1719}
1720
1721impl<O: OffsetSizeTrait> ByteArrayType for GenericBinaryType<O> {
1722 type Offset = O;
1723 type Native = [u8];
1724 const PREFIX: &'static str = "Binary";
1725
1726 const DATA_TYPE: DataType = if O::IS_LARGE {
1727 DataType::LargeBinary
1728 } else {
1729 DataType::Binary
1730 };
1731
1732 fn validate(offsets: &OffsetBuffer<Self::Offset>, values: &Buffer) -> Result<(), ArrowError> {
1733 let max_offset = offsets.last().as_usize();
1735 if values.len() < max_offset {
1736 return Err(ArrowError::InvalidArgumentError(format!(
1737 "Maximum offset of {max_offset} is larger than values of length {}",
1738 values.len()
1739 )));
1740 }
1741 Ok(())
1742 }
1743}
1744
1745pub type BinaryType = GenericBinaryType<i32>;
1747pub type LargeBinaryType = GenericBinaryType<i64>;
1749
1750mod byte_view {
1751 use crate::types::{BinaryViewType, StringViewType};
1752
1753 pub trait Sealed: Send + Sync {}
1754 impl Sealed for StringViewType {}
1755 impl Sealed for BinaryViewType {}
1756}
1757
1758pub trait ByteViewType: byte_view::Sealed + 'static + PartialEq + Send + Sync {
1760 const IS_UTF8: bool;
1762
1763 const DATA_TYPE: DataType = if Self::IS_UTF8 {
1765 DataType::Utf8View
1766 } else {
1767 DataType::BinaryView
1768 };
1769
1770 const PREFIX: &'static str;
1772
1773 type Native: bytes::ByteArrayNativeType + AsRef<Self::Native> + AsRef<[u8]> + ?Sized;
1777
1778 type Owned: Debug + Clone + Sync + Send + AsRef<Self::Native>;
1780
1781 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError>;
1783}
1784
1785#[derive(PartialEq)]
1787pub struct StringViewType {}
1788
1789impl ByteViewType for StringViewType {
1790 const IS_UTF8: bool = true;
1791 const PREFIX: &'static str = "String";
1792
1793 type Native = str;
1794 type Owned = String;
1795
1796 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1797 validate_string_view(views, buffers)
1798 }
1799}
1800
1801#[derive(PartialEq)]
1803pub struct BinaryViewType {}
1804
1805impl ByteViewType for BinaryViewType {
1806 const IS_UTF8: bool = false;
1807 const PREFIX: &'static str = "Binary";
1808 type Native = [u8];
1809 type Owned = Vec<u8>;
1810
1811 fn validate(views: &[u128], buffers: &[Buffer]) -> Result<(), ArrowError> {
1812 validate_binary_view(views, buffers)
1813 }
1814}
1815
1816#[cfg(test)]
1817mod tests {
1818 use super::*;
1819 use arrow_data::{BufferSpec, layout};
1820 use chrono::DateTime;
1821
1822 #[test]
1823 fn month_day_nano_should_roundtrip() {
1824 let value = IntervalMonthDayNanoType::make_value(1, 2, 3);
1825 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (1, 2, 3));
1826 }
1827
1828 #[test]
1829 fn month_day_nano_should_roundtrip_neg() {
1830 let value = IntervalMonthDayNanoType::make_value(-1, -2, -3);
1831 assert_eq!(IntervalMonthDayNanoType::to_parts(value), (-1, -2, -3));
1832 }
1833
1834 #[test]
1835 fn day_time_should_roundtrip() {
1836 let value = IntervalDayTimeType::make_value(1, 2);
1837 assert_eq!(IntervalDayTimeType::to_parts(value), (1, 2));
1838 }
1839
1840 #[test]
1841 fn day_time_should_roundtrip_neg() {
1842 let value = IntervalDayTimeType::make_value(-1, -2);
1843 assert_eq!(IntervalDayTimeType::to_parts(value), (-1, -2));
1844 }
1845
1846 #[test]
1847 fn year_month_should_roundtrip() {
1848 let value = IntervalYearMonthType::make_value(1, 2);
1849 assert_eq!(IntervalYearMonthType::to_months(value), 14);
1850 }
1851
1852 #[test]
1853 fn year_month_should_roundtrip_neg() {
1854 let value = IntervalYearMonthType::make_value(-1, -2);
1855 assert_eq!(IntervalYearMonthType::to_months(value), -14);
1856 }
1857
1858 #[test]
1859 fn date_subtract_i32_min_months_overflows() {
1860 assert!(Date32Type::subtract_year_months_opt(0, i32::MIN).is_none());
1864 assert!(Date64Type::subtract_year_months_opt(0, i32::MIN).is_none());
1865 assert!(Date32Type::add_year_months_opt(0, i32::MIN).is_none());
1867 assert!(Date64Type::add_year_months_opt(0, i32::MIN).is_none());
1868 assert!(
1869 Date32Type::subtract_month_day_nano_opt(0, IntervalMonthDayNano::new(i32::MIN, 0, 0))
1870 .is_none()
1871 );
1872 assert!(
1873 Date64Type::subtract_month_day_nano_opt(0, IntervalMonthDayNano::new(i32::MIN, 0, 0))
1874 .is_none()
1875 );
1876 assert!(
1878 Date32Type::subtract_month_day_nano_opt(0, IntervalMonthDayNano::new(i32::MIN, 1, 1))
1879 .is_none()
1880 );
1881 assert!(
1882 Date64Type::subtract_month_day_nano_opt(0, IntervalMonthDayNano::new(i32::MIN, 1, 1))
1883 .is_none()
1884 );
1885 }
1886
1887 fn test_layout<T: ArrowPrimitiveType>() {
1888 let layout = layout(&T::DATA_TYPE);
1889
1890 assert_eq!(layout.buffers.len(), 1);
1891
1892 let spec = &layout.buffers[0];
1893 assert_eq!(
1894 spec,
1895 &BufferSpec::FixedWidth {
1896 byte_width: std::mem::size_of::<T::Native>(),
1897 alignment: std::mem::align_of::<T::Native>(),
1898 }
1899 );
1900 }
1901
1902 #[test]
1903 fn test_layouts() {
1904 test_layout::<Int8Type>();
1905 test_layout::<Int16Type>();
1906 test_layout::<Int32Type>();
1907 test_layout::<Int64Type>();
1908 test_layout::<UInt8Type>();
1909 test_layout::<UInt16Type>();
1910 test_layout::<UInt32Type>();
1911 test_layout::<UInt64Type>();
1912 test_layout::<Float16Type>();
1913 test_layout::<Float32Type>();
1914 test_layout::<Float64Type>();
1915 test_layout::<Decimal32Type>();
1916 test_layout::<Decimal64Type>();
1917 test_layout::<Decimal128Type>();
1918 test_layout::<Decimal256Type>();
1919 test_layout::<TimestampNanosecondType>();
1920 test_layout::<TimestampMillisecondType>();
1921 test_layout::<TimestampMicrosecondType>();
1922 test_layout::<TimestampNanosecondType>();
1923 test_layout::<TimestampSecondType>();
1924 test_layout::<Date32Type>();
1925 test_layout::<Date64Type>();
1926 test_layout::<Time32SecondType>();
1927 test_layout::<Time32MillisecondType>();
1928 test_layout::<Time64MicrosecondType>();
1929 test_layout::<Time64NanosecondType>();
1930 test_layout::<IntervalMonthDayNanoType>();
1931 test_layout::<IntervalDayTimeType>();
1932 test_layout::<IntervalYearMonthType>();
1933 test_layout::<DurationNanosecondType>();
1934 test_layout::<DurationMicrosecondType>();
1935 test_layout::<DurationMillisecondType>();
1936 test_layout::<DurationSecondType>();
1937 }
1938
1939 #[test]
1940 fn timestamp_from_datetime() {
1941 use chrono::{FixedOffset, NaiveDate, NaiveTime, Utc};
1942
1943 let date = NaiveDate::from_ymd_opt(2021, 1, 1).unwrap();
1945 let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
1946 let naive = NaiveDateTime::new(date, time);
1947 let datetime_utc = Utc.from_utc_datetime(&naive);
1948
1949 assert_eq!(
1950 TimestampSecondType::from_datetime(datetime_utc).unwrap(),
1951 1609502400
1952 );
1953 assert_eq!(
1954 TimestampMillisecondType::from_datetime(datetime_utc).unwrap(),
1955 1609502400000
1956 );
1957 assert_eq!(
1958 TimestampMicrosecondType::from_datetime(datetime_utc).unwrap(),
1959 1609502400000000
1960 );
1961 assert_eq!(
1962 TimestampNanosecondType::from_datetime(datetime_utc).unwrap(),
1963 1609502400000000000
1964 );
1965
1966 let tz_plus_8 = FixedOffset::east_opt(8 * 3600).unwrap();
1968 let datetime_plus_8 = tz_plus_8.from_local_datetime(&naive).unwrap();
1969 assert_eq!(
1970 TimestampSecondType::from_datetime(datetime_plus_8).unwrap(),
1971 1609502400 - 28800
1972 );
1973
1974 let datetime = DateTime::from_timestamp(1000000000, 123456789).unwrap();
1976 assert_eq!(
1977 TimestampSecondType::from_datetime(datetime).unwrap(),
1978 1000000000
1979 );
1980 assert_eq!(
1981 TimestampMillisecondType::from_datetime(datetime).unwrap(),
1982 1000000000123
1983 );
1984 assert_eq!(
1985 TimestampMicrosecondType::from_datetime(datetime).unwrap(),
1986 1000000000123456
1987 );
1988 assert_eq!(
1989 TimestampNanosecondType::from_datetime(datetime).unwrap(),
1990 1000000000123456789
1991 );
1992 }
1993
1994 #[test]
1995 fn timestamp_from_datetime_overflow() {
1996 let far_past = DateTime::from_timestamp(-10_000_000_000, 0).unwrap();
1998 assert!(TimestampNanosecondType::from_datetime(far_past).is_none());
1999 assert!(TimestampSecondType::from_datetime(far_past).is_some());
2001 assert!(TimestampMillisecondType::from_datetime(far_past).is_some());
2002 assert!(TimestampMicrosecondType::from_datetime(far_past).is_some());
2003
2004 let far_future = DateTime::from_timestamp(10_000_000_000, 0).unwrap();
2005 assert!(TimestampNanosecondType::from_datetime(far_future).is_none());
2006 assert!(TimestampSecondType::from_datetime(far_future).is_some());
2007 assert!(TimestampMillisecondType::from_datetime(far_future).is_some());
2008 assert!(TimestampMicrosecondType::from_datetime(far_future).is_some());
2009 }
2010
2011 #[test]
2012 fn timestamp_from_naive_datetime() {
2013 use crate::temporal_conversions::as_datetime_with_timezone;
2014 use chrono::{NaiveDate, NaiveTime};
2015
2016 let date = NaiveDate::from_ymd_opt(2021, 1, 1).unwrap();
2017 let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
2018 let naive = NaiveDateTime::new(date, time);
2019
2020 assert_eq!(
2022 TimestampSecondType::from_naive_datetime(naive, None).unwrap(),
2023 1609502400
2024 );
2025 assert_eq!(
2026 TimestampMillisecondType::from_naive_datetime(naive, None).unwrap(),
2027 1609502400000
2028 );
2029
2030 let tz: Tz = "-05:00".parse().unwrap();
2032 let ts_sec = TimestampSecondType::from_naive_datetime(naive, Some(&tz)).unwrap();
2033 assert_eq!(ts_sec, 1609502400 + 5 * 3600);
2034
2035 let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();
2037 let time = NaiveTime::from_hms_opt(14, 30, 45).unwrap();
2038 let naive = NaiveDateTime::new(date, time);
2039 let tz: Tz = "+01:00".parse().unwrap();
2040
2041 let ts_usec = TimestampMicrosecondType::from_naive_datetime(naive, Some(&tz)).unwrap();
2042 let recovered = as_datetime_with_timezone::<TimestampMicrosecondType>(ts_usec, tz).unwrap();
2043 assert_eq!(recovered.naive_local(), naive);
2044 }
2045
2046 #[test]
2047 #[cfg(feature = "chrono-tz")]
2048 fn timestamp_from_naive_datetime_ambiguous() {
2049 use chrono::{NaiveDate, NaiveTime};
2050
2051 let date = NaiveDate::from_ymd_opt(2024, 11, 3).unwrap();
2054 let time = NaiveTime::from_hms_opt(1, 30, 0).unwrap();
2055 let naive = NaiveDateTime::new(date, time);
2056 let tz: Tz = "America/New_York".parse().unwrap();
2057
2058 let result = TimestampSecondType::from_naive_datetime(naive, Some(&tz));
2060 assert!(result.is_some());
2061 assert_eq!(result.unwrap(), 1730611800);
2062 }
2063
2064 #[test]
2065 #[cfg(feature = "chrono-tz")]
2066 fn timestamp_from_naive_datetime_none() {
2067 use chrono::{NaiveDate, NaiveTime};
2068
2069 let date = NaiveDate::from_ymd_opt(2024, 3, 10).unwrap();
2072 let time = NaiveTime::from_hms_opt(2, 30, 0).unwrap();
2073 let naive = NaiveDateTime::new(date, time);
2074 let tz: Tz = "America/New_York".parse().unwrap();
2075
2076 let result = TimestampSecondType::from_naive_datetime(naive, Some(&tz));
2078 assert!(result.is_none());
2079
2080 assert!(TimestampMillisecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2082 assert!(TimestampMicrosecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2083 assert!(TimestampNanosecondType::from_naive_datetime(naive, Some(&tz)).is_none());
2084 }
2085}