1use std::sync::Arc;
21
22use arrow_array::cast::AsArray;
23use cast::as_primitive_array;
24use chrono::{Datelike, TimeZone, Timelike, Utc};
25
26use arrow_array::temporal_conversions::{
27 date32_to_datetime, date64_to_datetime, timestamp_ms_to_datetime, timestamp_ns_to_datetime,
28 timestamp_s_to_datetime, timestamp_us_to_datetime, MICROSECONDS, MICROSECONDS_IN_DAY,
29 MILLISECONDS, MILLISECONDS_IN_DAY, NANOSECONDS, NANOSECONDS_IN_DAY, SECONDS_IN_DAY,
30};
31use arrow_array::timezone::Tz;
32use arrow_array::types::*;
33use arrow_array::*;
34use arrow_buffer::ArrowNativeType;
35use arrow_schema::{ArrowError, DataType, IntervalUnit, TimeUnit};
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44#[non_exhaustive]
45pub enum DatePart {
46 Quarter,
48 Year,
50 Month,
52 Week,
54 Day,
56 DayOfWeekSunday0,
58 DayOfWeekMonday0,
60 DayOfYear,
62 Hour,
64 Minute,
66 Second,
68 Millisecond,
70 Microsecond,
72 Nanosecond,
74}
75
76impl std::fmt::Display for DatePart {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 write!(f, "{:?}", self)
79 }
80}
81
82fn get_date_time_part_extract_fn<T>(part: DatePart) -> fn(T) -> i32
88where
89 T: ChronoDateExt + Datelike + Timelike,
90{
91 match part {
92 DatePart::Quarter => |d| d.quarter() as i32,
93 DatePart::Year => |d| d.year(),
94 DatePart::Month => |d| d.month() as i32,
95 DatePart::Week => |d| d.iso_week().week() as i32,
96 DatePart::Day => |d| d.day() as i32,
97 DatePart::DayOfWeekSunday0 => |d| d.num_days_from_sunday(),
98 DatePart::DayOfWeekMonday0 => |d| d.num_days_from_monday(),
99 DatePart::DayOfYear => |d| d.ordinal() as i32,
100 DatePart::Hour => |d| d.hour() as i32,
101 DatePart::Minute => |d| d.minute() as i32,
102 DatePart::Second => |d| d.second() as i32,
103 DatePart::Millisecond => |d| (d.nanosecond() / 1_000_000) as i32,
104 DatePart::Microsecond => |d| (d.nanosecond() / 1_000) as i32,
105 DatePart::Nanosecond => |d| (d.nanosecond()) as i32,
106 }
107}
108
109pub fn date_part(array: &dyn Array, part: DatePart) -> Result<ArrayRef, ArrowError> {
138 downcast_temporal_array!(
139 array => {
140 let array = array.date_part(part)?;
141 let array = Arc::new(array) as ArrayRef;
142 Ok(array)
143 }
144 DataType::Interval(IntervalUnit::YearMonth) => {
145 let array = as_primitive_array::<IntervalYearMonthType>(array).date_part(part)?;
146 let array = Arc::new(array) as ArrayRef;
147 Ok(array)
148 }
149 DataType::Interval(IntervalUnit::DayTime) => {
150 let array = as_primitive_array::<IntervalDayTimeType>(array).date_part(part)?;
151 let array = Arc::new(array) as ArrayRef;
152 Ok(array)
153 }
154 DataType::Interval(IntervalUnit::MonthDayNano) => {
155 let array = as_primitive_array::<IntervalMonthDayNanoType>(array).date_part(part)?;
156 let array = Arc::new(array) as ArrayRef;
157 Ok(array)
158 }
159 DataType::Duration(TimeUnit::Second) => {
160 let array = as_primitive_array::<DurationSecondType>(array).date_part(part)?;
161 let array = Arc::new(array) as ArrayRef;
162 Ok(array)
163 }
164 DataType::Duration(TimeUnit::Millisecond) => {
165 let array = as_primitive_array::<DurationMillisecondType>(array).date_part(part)?;
166 let array = Arc::new(array) as ArrayRef;
167 Ok(array)
168 }
169 DataType::Duration(TimeUnit::Microsecond) => {
170 let array = as_primitive_array::<DurationMicrosecondType>(array).date_part(part)?;
171 let array = Arc::new(array) as ArrayRef;
172 Ok(array)
173 }
174 DataType::Duration(TimeUnit::Nanosecond) => {
175 let array = as_primitive_array::<DurationNanosecondType>(array).date_part(part)?;
176 let array = Arc::new(array) as ArrayRef;
177 Ok(array)
178 }
179 DataType::Dictionary(_, _) => {
180 let array = array.as_any_dictionary();
181 let values = date_part(array.values(), part)?;
182 let values = Arc::new(values) as ArrayRef;
183 let new_array = array.with_values(values);
184 Ok(new_array)
185 }
186 t => return_compute_error_with!(format!("{part} does not support"), t),
187 )
188}
189
190fn date_part_primitive<T: ArrowTemporalType>(
193 array: &PrimitiveArray<T>,
194 part: DatePart,
195) -> Result<Int32Array, ArrowError> {
196 let array = date_part(array, part)?;
197 Ok(array.as_primitive::<Int32Type>().to_owned())
198}
199
200fn get_tz(dt: &DataType) -> Result<Option<Tz>, ArrowError> {
203 match dt {
204 DataType::Timestamp(_, Some(tz)) => Ok(Some(tz.parse::<Tz>()?)),
205 DataType::Timestamp(_, None) => Ok(None),
206 _ => Err(ArrowError::CastError(format!("Not a timestamp type: {dt}"))),
207 }
208}
209
210trait ExtractDatePartExt {
212 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError>;
213}
214
215impl ExtractDatePartExt for PrimitiveArray<Time32SecondType> {
216 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
217 #[inline]
218 fn range_check(s: i32) -> bool {
219 (0..SECONDS_IN_DAY as i32).contains(&s)
220 }
221 match part {
222 DatePart::Hour => Ok(self.unary_opt(|s| range_check(s).then_some(s / 3_600))),
223 DatePart::Minute => Ok(self.unary_opt(|s| range_check(s).then_some((s / 60) % 60))),
224 DatePart::Second => Ok(self.unary_opt(|s| range_check(s).then_some(s % 60))),
225 DatePart::Millisecond | DatePart::Microsecond | DatePart::Nanosecond => {
227 Ok(self.unary_opt(|s| range_check(s).then_some(0)))
228 }
229 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
230 }
231 }
232}
233
234impl ExtractDatePartExt for PrimitiveArray<Time32MillisecondType> {
235 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
236 #[inline]
237 fn range_check(ms: i32) -> bool {
238 (0..MILLISECONDS_IN_DAY as i32).contains(&ms)
239 }
240 let milliseconds = MILLISECONDS as i32;
241 match part {
242 DatePart::Hour => {
243 Ok(self.unary_opt(|ms| range_check(ms).then_some(ms / 3_600 / milliseconds)))
244 }
245 DatePart::Minute => {
246 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms / 60 / milliseconds) % 60)))
247 }
248 DatePart::Second => {
249 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms / milliseconds) % 60)))
250 }
251 DatePart::Millisecond => {
252 Ok(self.unary_opt(|ms| range_check(ms).then_some(ms % milliseconds)))
253 }
254 DatePart::Microsecond => {
255 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms % milliseconds) * 1_000)))
256 }
257 DatePart::Nanosecond => {
258 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms % milliseconds) * 1_000_000)))
259 }
260 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
261 }
262 }
263}
264
265impl ExtractDatePartExt for PrimitiveArray<Time64MicrosecondType> {
266 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
267 #[inline]
268 fn range_check(us: i64) -> bool {
269 (0..MICROSECONDS_IN_DAY).contains(&us)
270 }
271 match part {
272 DatePart::Hour => {
273 Ok(self
274 .unary_opt(|us| range_check(us).then_some((us / 3_600 / MICROSECONDS) as i32)))
275 }
276 DatePart::Minute => Ok(self
277 .unary_opt(|us| range_check(us).then_some(((us / 60 / MICROSECONDS) % 60) as i32))),
278 DatePart::Second => {
279 Ok(self
280 .unary_opt(|us| range_check(us).then_some(((us / MICROSECONDS) % 60) as i32)))
281 }
282 DatePart::Millisecond => Ok(self
283 .unary_opt(|us| range_check(us).then_some(((us % MICROSECONDS) / 1_000) as i32))),
284 DatePart::Microsecond => {
285 Ok(self.unary_opt(|us| range_check(us).then_some((us % MICROSECONDS) as i32)))
286 }
287 DatePart::Nanosecond => Ok(self
288 .unary_opt(|us| range_check(us).then_some(((us % MICROSECONDS) * 1_000) as i32))),
289 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
290 }
291 }
292}
293
294impl ExtractDatePartExt for PrimitiveArray<Time64NanosecondType> {
295 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
296 #[inline]
297 fn range_check(ns: i64) -> bool {
298 (0..NANOSECONDS_IN_DAY).contains(&ns)
299 }
300 match part {
301 DatePart::Hour => {
302 Ok(self
303 .unary_opt(|ns| range_check(ns).then_some((ns / 3_600 / NANOSECONDS) as i32)))
304 }
305 DatePart::Minute => Ok(self
306 .unary_opt(|ns| range_check(ns).then_some(((ns / 60 / NANOSECONDS) % 60) as i32))),
307 DatePart::Second => Ok(
308 self.unary_opt(|ns| range_check(ns).then_some(((ns / NANOSECONDS) % 60) as i32))
309 ),
310 DatePart::Millisecond => Ok(self.unary_opt(|ns| {
311 range_check(ns).then_some(((ns % NANOSECONDS) / 1_000_000) as i32)
312 })),
313 DatePart::Microsecond => {
314 Ok(self
315 .unary_opt(|ns| range_check(ns).then_some(((ns % NANOSECONDS) / 1_000) as i32)))
316 }
317 DatePart::Nanosecond => {
318 Ok(self.unary_opt(|ns| range_check(ns).then_some((ns % NANOSECONDS) as i32)))
319 }
320 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
321 }
322 }
323}
324
325impl ExtractDatePartExt for PrimitiveArray<Date32Type> {
326 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
327 if let DatePart::Hour
329 | DatePart::Minute
330 | DatePart::Second
331 | DatePart::Millisecond
332 | DatePart::Microsecond
333 | DatePart::Nanosecond = part
334 {
335 Ok(Int32Array::new(
336 vec![0; self.len()].into(),
337 self.nulls().cloned(),
338 ))
339 } else {
340 let map_func = get_date_time_part_extract_fn(part);
341 Ok(self.unary_opt(|d| date32_to_datetime(d).map(map_func)))
342 }
343 }
344}
345
346impl ExtractDatePartExt for PrimitiveArray<Date64Type> {
347 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
348 let map_func = get_date_time_part_extract_fn(part);
349 Ok(self.unary_opt(|d| date64_to_datetime(d).map(map_func)))
350 }
351}
352
353impl ExtractDatePartExt for PrimitiveArray<TimestampSecondType> {
354 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
355 let array =
357 if let DatePart::Millisecond | DatePart::Microsecond | DatePart::Nanosecond = part {
358 Int32Array::new(vec![0; self.len()].into(), self.nulls().cloned())
359 } else if let Some(tz) = get_tz(self.data_type())? {
360 let map_func = get_date_time_part_extract_fn(part);
361 self.unary_opt(|d| {
362 timestamp_s_to_datetime(d)
363 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
364 .map(map_func)
365 })
366 } else {
367 let map_func = get_date_time_part_extract_fn(part);
368 self.unary_opt(|d| timestamp_s_to_datetime(d).map(map_func))
369 };
370 Ok(array)
371 }
372}
373
374impl ExtractDatePartExt for PrimitiveArray<TimestampMillisecondType> {
375 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
376 let array = if let Some(tz) = get_tz(self.data_type())? {
377 let map_func = get_date_time_part_extract_fn(part);
378 self.unary_opt(|d| {
379 timestamp_ms_to_datetime(d)
380 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
381 .map(map_func)
382 })
383 } else {
384 let map_func = get_date_time_part_extract_fn(part);
385 self.unary_opt(|d| timestamp_ms_to_datetime(d).map(map_func))
386 };
387 Ok(array)
388 }
389}
390
391impl ExtractDatePartExt for PrimitiveArray<TimestampMicrosecondType> {
392 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
393 let array = if let Some(tz) = get_tz(self.data_type())? {
394 let map_func = get_date_time_part_extract_fn(part);
395 self.unary_opt(|d| {
396 timestamp_us_to_datetime(d)
397 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
398 .map(map_func)
399 })
400 } else {
401 let map_func = get_date_time_part_extract_fn(part);
402 self.unary_opt(|d| timestamp_us_to_datetime(d).map(map_func))
403 };
404 Ok(array)
405 }
406}
407
408impl ExtractDatePartExt for PrimitiveArray<TimestampNanosecondType> {
409 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
410 let array = if let Some(tz) = get_tz(self.data_type())? {
411 let map_func = get_date_time_part_extract_fn(part);
412 self.unary_opt(|d| {
413 timestamp_ns_to_datetime(d)
414 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
415 .map(map_func)
416 })
417 } else {
418 let map_func = get_date_time_part_extract_fn(part);
419 self.unary_opt(|d| timestamp_ns_to_datetime(d).map(map_func))
420 };
421 Ok(array)
422 }
423}
424
425impl ExtractDatePartExt for PrimitiveArray<IntervalYearMonthType> {
426 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
427 match part {
428 DatePart::Year => Ok(self.unary_opt(|d| Some(d / 12))),
429 DatePart::Month => Ok(self.unary_opt(|d| Some(d % 12))),
430
431 DatePart::Quarter
432 | DatePart::Week
433 | DatePart::Day
434 | DatePart::DayOfWeekSunday0
435 | DatePart::DayOfWeekMonday0
436 | DatePart::DayOfYear
437 | DatePart::Hour
438 | DatePart::Minute
439 | DatePart::Second
440 | DatePart::Millisecond
441 | DatePart::Microsecond
442 | DatePart::Nanosecond => {
443 return_compute_error_with!(format!("{part} does not support"), self.data_type())
444 }
445 }
446 }
447}
448
449impl ExtractDatePartExt for PrimitiveArray<IntervalDayTimeType> {
450 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
451 match part {
452 DatePart::Week => Ok(self.unary_opt(|d| Some(d.days / 7))),
453 DatePart::Day => Ok(self.unary_opt(|d| Some(d.days))),
454 DatePart::Hour => Ok(self.unary_opt(|d| Some(d.milliseconds / (60 * 60 * 1_000)))),
455 DatePart::Minute => Ok(self.unary_opt(|d| Some(d.milliseconds / (60 * 1_000)))),
456 DatePart::Second => Ok(self.unary_opt(|d| Some(d.milliseconds / 1_000))),
457 DatePart::Millisecond => Ok(self.unary_opt(|d| Some(d.milliseconds))),
458 DatePart::Microsecond => Ok(self.unary_opt(|d| d.milliseconds.checked_mul(1_000))),
459 DatePart::Nanosecond => Ok(self.unary_opt(|d| d.milliseconds.checked_mul(1_000_000))),
460
461 DatePart::Quarter
462 | DatePart::Year
463 | DatePart::Month
464 | DatePart::DayOfWeekSunday0
465 | DatePart::DayOfWeekMonday0
466 | DatePart::DayOfYear => {
467 return_compute_error_with!(format!("{part} does not support"), self.data_type())
468 }
469 }
470 }
471}
472
473impl ExtractDatePartExt for PrimitiveArray<IntervalMonthDayNanoType> {
474 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
475 match part {
476 DatePart::Year => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.months / 12))),
477 DatePart::Month => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.months))),
478 DatePart::Week => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.days / 7))),
479 DatePart::Day => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.days))),
480 DatePart::Hour => {
481 Ok(self.unary_opt(|d| (d.nanoseconds / (60 * 60 * 1_000_000_000)).try_into().ok()))
482 }
483 DatePart::Minute => {
484 Ok(self.unary_opt(|d| (d.nanoseconds / (60 * 1_000_000_000)).try_into().ok()))
485 }
486 DatePart::Second => {
487 Ok(self.unary_opt(|d| (d.nanoseconds / 1_000_000_000).try_into().ok()))
488 }
489 DatePart::Millisecond => {
490 Ok(self.unary_opt(|d| (d.nanoseconds / 1_000_000).try_into().ok()))
491 }
492 DatePart::Microsecond => {
493 Ok(self.unary_opt(|d| (d.nanoseconds / 1_000).try_into().ok()))
494 }
495 DatePart::Nanosecond => Ok(self.unary_opt(|d| d.nanoseconds.try_into().ok())),
496
497 DatePart::Quarter
498 | DatePart::DayOfWeekSunday0
499 | DatePart::DayOfWeekMonday0
500 | DatePart::DayOfYear => {
501 return_compute_error_with!(format!("{part} does not support"), self.data_type())
502 }
503 }
504 }
505}
506
507impl ExtractDatePartExt for PrimitiveArray<DurationSecondType> {
508 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
509 match part {
510 DatePart::Week => Ok(self.unary_opt(|d| (d / (60 * 60 * 24 * 7)).try_into().ok())),
511 DatePart::Day => Ok(self.unary_opt(|d| (d / (60 * 60 * 24)).try_into().ok())),
512 DatePart::Hour => Ok(self.unary_opt(|d| (d / (60 * 60)).try_into().ok())),
513 DatePart::Minute => Ok(self.unary_opt(|d| (d / 60).try_into().ok())),
514 DatePart::Second => Ok(self.unary_opt(|d| d.try_into().ok())),
515 DatePart::Millisecond => {
516 Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
517 }
518 DatePart::Microsecond => {
519 Ok(self.unary_opt(|d| d.checked_mul(1_000_000).and_then(|d| d.try_into().ok())))
520 }
521 DatePart::Nanosecond => Ok(
522 self.unary_opt(|d| d.checked_mul(1_000_000_000).and_then(|d| d.try_into().ok()))
523 ),
524
525 DatePart::Year
526 | DatePart::Quarter
527 | DatePart::Month
528 | DatePart::DayOfWeekSunday0
529 | DatePart::DayOfWeekMonday0
530 | DatePart::DayOfYear => {
531 return_compute_error_with!(format!("{part} does not support"), self.data_type())
532 }
533 }
534 }
535}
536
537impl ExtractDatePartExt for PrimitiveArray<DurationMillisecondType> {
538 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
539 match part {
540 DatePart::Week => {
541 Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60 * 24 * 7)).try_into().ok()))
542 }
543 DatePart::Day => Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60 * 24)).try_into().ok())),
544 DatePart::Hour => Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60)).try_into().ok())),
545 DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000 * 60)).try_into().ok())),
546 DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
547 DatePart::Millisecond => Ok(self.unary_opt(|d| d.try_into().ok())),
548 DatePart::Microsecond => {
549 Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
550 }
551 DatePart::Nanosecond => {
552 Ok(self.unary_opt(|d| d.checked_mul(1_000_000).and_then(|d| d.try_into().ok())))
553 }
554
555 DatePart::Year
556 | DatePart::Quarter
557 | DatePart::Month
558 | DatePart::DayOfWeekSunday0
559 | DatePart::DayOfWeekMonday0
560 | DatePart::DayOfYear => {
561 return_compute_error_with!(format!("{part} does not support"), self.data_type())
562 }
563 }
564 }
565}
566
567impl ExtractDatePartExt for PrimitiveArray<DurationMicrosecondType> {
568 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
569 match part {
570 DatePart::Week => {
571 Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60 * 24 * 7)).try_into().ok()))
572 }
573 DatePart::Day => {
574 Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60 * 24)).try_into().ok()))
575 }
576 DatePart::Hour => Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60)).try_into().ok())),
577 DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000_000 * 60)).try_into().ok())),
578 DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000_000).try_into().ok())),
579 DatePart::Millisecond => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
580 DatePart::Microsecond => Ok(self.unary_opt(|d| d.try_into().ok())),
581 DatePart::Nanosecond => {
582 Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
583 }
584
585 DatePart::Year
586 | DatePart::Quarter
587 | DatePart::Month
588 | DatePart::DayOfWeekSunday0
589 | DatePart::DayOfWeekMonday0
590 | DatePart::DayOfYear => {
591 return_compute_error_with!(format!("{part} does not support"), self.data_type())
592 }
593 }
594 }
595}
596
597impl ExtractDatePartExt for PrimitiveArray<DurationNanosecondType> {
598 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
599 match part {
600 DatePart::Week => {
601 Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60 * 24 * 7)).try_into().ok()))
602 }
603 DatePart::Day => {
604 Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60 * 24)).try_into().ok()))
605 }
606 DatePart::Hour => {
607 Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60)).try_into().ok()))
608 }
609 DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60)).try_into().ok())),
610 DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000_000_000).try_into().ok())),
611 DatePart::Millisecond => Ok(self.unary_opt(|d| (d / 1_000_000).try_into().ok())),
612 DatePart::Microsecond => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
613 DatePart::Nanosecond => Ok(self.unary_opt(|d| d.try_into().ok())),
614
615 DatePart::Year
616 | DatePart::Quarter
617 | DatePart::Month
618 | DatePart::DayOfWeekSunday0
619 | DatePart::DayOfWeekMonday0
620 | DatePart::DayOfYear => {
621 return_compute_error_with!(format!("{part} does not support"), self.data_type())
622 }
623 }
624 }
625}
626
627macro_rules! return_compute_error_with {
628 ($msg:expr, $param:expr) => {
629 return { Err(ArrowError::ComputeError(format!("{}: {:?}", $msg, $param))) }
630 };
631}
632
633pub(crate) use return_compute_error_with;
634
635trait ChronoDateExt {
637 fn quarter(&self) -> u32;
639
640 fn quarter0(&self) -> u32;
642
643 fn num_days_from_monday(&self) -> i32;
645
646 fn num_days_from_sunday(&self) -> i32;
648}
649
650impl<T: Datelike> ChronoDateExt for T {
651 fn quarter(&self) -> u32 {
652 self.quarter0() + 1
653 }
654
655 fn quarter0(&self) -> u32 {
656 self.month0() / 3
657 }
658
659 fn num_days_from_monday(&self) -> i32 {
660 self.weekday().num_days_from_monday() as i32
661 }
662
663 fn num_days_from_sunday(&self) -> i32 {
664 self.weekday().num_days_from_sunday() as i32
665 }
666}
667
668#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
672pub fn hour_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
673 date_part(array, DatePart::Hour)
674}
675
676#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
679pub fn hour<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
680where
681 T: ArrowTemporalType + ArrowNumericType,
682 i64: From<T::Native>,
683{
684 date_part_primitive(array, DatePart::Hour)
685}
686
687#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
691pub fn year_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
692 date_part(array, DatePart::Year)
693}
694
695#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
697pub fn year<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
698where
699 T: ArrowTemporalType + ArrowNumericType,
700 i64: From<T::Native>,
701{
702 date_part_primitive(array, DatePart::Year)
703}
704
705#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
709pub fn quarter_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
710 date_part(array, DatePart::Quarter)
711}
712
713#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
716pub fn quarter<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
717where
718 T: ArrowTemporalType + ArrowNumericType,
719 i64: From<T::Native>,
720{
721 date_part_primitive(array, DatePart::Quarter)
722}
723
724#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
728pub fn month_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
729 date_part(array, DatePart::Month)
730}
731
732#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
735pub fn month<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
736where
737 T: ArrowTemporalType + ArrowNumericType,
738 i64: From<T::Native>,
739{
740 date_part_primitive(array, DatePart::Month)
741}
742
743#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
753pub fn num_days_from_monday_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
754 date_part(array, DatePart::DayOfWeekMonday0)
755}
756
757#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
764pub fn num_days_from_monday<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
765where
766 T: ArrowTemporalType + ArrowNumericType,
767 i64: From<T::Native>,
768{
769 date_part_primitive(array, DatePart::DayOfWeekMonday0)
770}
771
772#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
782pub fn num_days_from_sunday_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
783 date_part(array, DatePart::DayOfWeekSunday0)
784}
785
786#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
793pub fn num_days_from_sunday<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
794where
795 T: ArrowTemporalType + ArrowNumericType,
796 i64: From<T::Native>,
797{
798 date_part_primitive(array, DatePart::DayOfWeekSunday0)
799}
800
801#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
806pub fn day_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
807 date_part(array, DatePart::Day)
808}
809
810#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
812pub fn day<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
813where
814 T: ArrowTemporalType + ArrowNumericType,
815 i64: From<T::Native>,
816{
817 date_part_primitive(array, DatePart::Day)
818}
819
820#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
826pub fn doy_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
827 date_part(array, DatePart::DayOfYear)
828}
829
830#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
834pub fn doy<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
835where
836 T: ArrowTemporalType + ArrowNumericType,
837 T::Native: ArrowNativeType,
838 i64: From<T::Native>,
839{
840 date_part_primitive(array, DatePart::DayOfYear)
841}
842
843#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
845pub fn minute<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
846where
847 T: ArrowTemporalType + ArrowNumericType,
848 i64: From<T::Native>,
849{
850 date_part_primitive(array, DatePart::Minute)
851}
852
853#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
857pub fn week_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
858 date_part(array, DatePart::Week)
859}
860
861#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
863pub fn week<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
864where
865 T: ArrowTemporalType + ArrowNumericType,
866 i64: From<T::Native>,
867{
868 date_part_primitive(array, DatePart::Week)
869}
870
871#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
873pub fn second<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
874where
875 T: ArrowTemporalType + ArrowNumericType,
876 i64: From<T::Native>,
877{
878 date_part_primitive(array, DatePart::Second)
879}
880
881#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
883pub fn nanosecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
884where
885 T: ArrowTemporalType + ArrowNumericType,
886 i64: From<T::Native>,
887{
888 date_part_primitive(array, DatePart::Nanosecond)
889}
890
891#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
895pub fn nanosecond_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
896 date_part(array, DatePart::Nanosecond)
897}
898
899#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
901pub fn microsecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
902where
903 T: ArrowTemporalType + ArrowNumericType,
904 i64: From<T::Native>,
905{
906 date_part_primitive(array, DatePart::Microsecond)
907}
908
909#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
913pub fn microsecond_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
914 date_part(array, DatePart::Microsecond)
915}
916
917#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
919pub fn millisecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
920where
921 T: ArrowTemporalType + ArrowNumericType,
922 i64: From<T::Native>,
923{
924 date_part_primitive(array, DatePart::Millisecond)
925}
926
927#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
931pub fn millisecond_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
932 date_part(array, DatePart::Millisecond)
933}
934
935#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
939pub fn minute_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
940 date_part(array, DatePart::Minute)
941}
942
943#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
947pub fn second_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
948 date_part(array, DatePart::Second)
949}
950
951#[cfg(test)]
952#[allow(deprecated)]
953mod tests {
954 use super::*;
955
956 #[test]
957 fn test_temporal_array_date64_hour() {
958 let a: PrimitiveArray<Date64Type> =
959 vec![Some(1514764800000), None, Some(1550636625000)].into();
960
961 let b = hour(&a).unwrap();
962 assert_eq!(0, b.value(0));
963 assert!(!b.is_valid(1));
964 assert_eq!(4, b.value(2));
965 }
966
967 #[test]
968 fn test_temporal_array_date32_hour() {
969 let a: PrimitiveArray<Date32Type> = vec![Some(15147), None, Some(15148)].into();
970
971 let b = hour(&a).unwrap();
972 assert_eq!(0, b.value(0));
973 assert!(!b.is_valid(1));
974 assert_eq!(0, b.value(2));
975 }
976
977 #[test]
978 fn test_temporal_array_time32_second_hour() {
979 let a: PrimitiveArray<Time32SecondType> = vec![37800, 86339].into();
980
981 let b = hour(&a).unwrap();
982 assert_eq!(10, b.value(0));
983 assert_eq!(23, b.value(1));
984 }
985
986 #[test]
987 fn test_temporal_array_time64_micro_hour() {
988 let a: PrimitiveArray<Time64MicrosecondType> = vec![37800000000, 86339000000].into();
989
990 let b = hour(&a).unwrap();
991 assert_eq!(10, b.value(0));
992 assert_eq!(23, b.value(1));
993 }
994
995 #[test]
996 fn test_temporal_array_timestamp_micro_hour() {
997 let a: TimestampMicrosecondArray = vec![37800000000, 86339000000].into();
998
999 let b = hour(&a).unwrap();
1000 assert_eq!(10, b.value(0));
1001 assert_eq!(23, b.value(1));
1002 }
1003
1004 #[test]
1005 fn test_temporal_array_date64_year() {
1006 let a: PrimitiveArray<Date64Type> =
1007 vec![Some(1514764800000), None, Some(1550636625000)].into();
1008
1009 let b = year(&a).unwrap();
1010 assert_eq!(2018, b.value(0));
1011 assert!(!b.is_valid(1));
1012 assert_eq!(2019, b.value(2));
1013 }
1014
1015 #[test]
1016 fn test_temporal_array_date32_year() {
1017 let a: PrimitiveArray<Date32Type> = vec![Some(15147), None, Some(15448)].into();
1018
1019 let b = year(&a).unwrap();
1020 assert_eq!(2011, b.value(0));
1021 assert!(!b.is_valid(1));
1022 assert_eq!(2012, b.value(2));
1023 }
1024
1025 #[test]
1026 fn test_temporal_array_date64_quarter() {
1027 let a: PrimitiveArray<Date64Type> =
1030 vec![Some(1514764800000), None, Some(1566275025000)].into();
1031
1032 let b = quarter(&a).unwrap();
1033 assert_eq!(1, b.value(0));
1034 assert!(!b.is_valid(1));
1035 assert_eq!(3, b.value(2));
1036 }
1037
1038 #[test]
1039 fn test_temporal_array_date32_quarter() {
1040 let a: PrimitiveArray<Date32Type> = vec![Some(1), None, Some(300)].into();
1041
1042 let b = quarter(&a).unwrap();
1043 assert_eq!(1, b.value(0));
1044 assert!(!b.is_valid(1));
1045 assert_eq!(4, b.value(2));
1046 }
1047
1048 #[test]
1049 fn test_temporal_array_timestamp_quarter_with_timezone() {
1050 let a = TimestampSecondArray::from(vec![86400 * 90]).with_timezone("+00:00".to_string());
1052 let b = quarter(&a).unwrap();
1053 assert_eq!(2, b.value(0));
1054 let a = TimestampSecondArray::from(vec![86400 * 90]).with_timezone("-10:00".to_string());
1055 let b = quarter(&a).unwrap();
1056 assert_eq!(1, b.value(0));
1057 }
1058
1059 #[test]
1060 fn test_temporal_array_date64_month() {
1061 let a: PrimitiveArray<Date64Type> =
1064 vec![Some(1514764800000), None, Some(1550636625000)].into();
1065
1066 let b = month(&a).unwrap();
1067 assert_eq!(1, b.value(0));
1068 assert!(!b.is_valid(1));
1069 assert_eq!(2, b.value(2));
1070 }
1071
1072 #[test]
1073 fn test_temporal_array_date32_month() {
1074 let a: PrimitiveArray<Date32Type> = vec![Some(1), None, Some(31)].into();
1075
1076 let b = month(&a).unwrap();
1077 assert_eq!(1, b.value(0));
1078 assert!(!b.is_valid(1));
1079 assert_eq!(2, b.value(2));
1080 }
1081
1082 #[test]
1083 fn test_temporal_array_timestamp_month_with_timezone() {
1084 let a = TimestampSecondArray::from(vec![86400 * 31]).with_timezone("+00:00".to_string());
1086 let b = month(&a).unwrap();
1087 assert_eq!(2, b.value(0));
1088 let a = TimestampSecondArray::from(vec![86400 * 31]).with_timezone("-10:00".to_string());
1089 let b = month(&a).unwrap();
1090 assert_eq!(1, b.value(0));
1091 }
1092
1093 #[test]
1094 fn test_temporal_array_timestamp_day_with_timezone() {
1095 let a = TimestampSecondArray::from(vec![86400]).with_timezone("+00:00".to_string());
1097 let b = day(&a).unwrap();
1098 assert_eq!(2, b.value(0));
1099 let a = TimestampSecondArray::from(vec![86400]).with_timezone("-10:00".to_string());
1100 let b = day(&a).unwrap();
1101 assert_eq!(1, b.value(0));
1102 }
1103
1104 #[test]
1105 fn test_temporal_array_date64_weekday() {
1106 let a: PrimitiveArray<Date64Type> =
1109 vec![Some(1514764800000), None, Some(1550636625000)].into();
1110
1111 let b = num_days_from_monday(&a).unwrap();
1112 assert_eq!(0, b.value(0));
1113 assert!(!b.is_valid(1));
1114 assert_eq!(2, b.value(2));
1115 }
1116
1117 #[test]
1118 fn test_temporal_array_date64_weekday0() {
1119 let a: PrimitiveArray<Date64Type> = vec![
1123 Some(1483228800000),
1124 None,
1125 Some(1514764800000),
1126 Some(1550636625000),
1127 ]
1128 .into();
1129
1130 let b = num_days_from_sunday(&a).unwrap();
1131 assert_eq!(0, b.value(0));
1132 assert!(!b.is_valid(1));
1133 assert_eq!(1, b.value(2));
1134 assert_eq!(3, b.value(3));
1135 }
1136
1137 #[test]
1138 fn test_temporal_array_date64_day() {
1139 let a: PrimitiveArray<Date64Type> =
1142 vec![Some(1514764800000), None, Some(1550636625000)].into();
1143
1144 let b = day(&a).unwrap();
1145 assert_eq!(1, b.value(0));
1146 assert!(!b.is_valid(1));
1147 assert_eq!(20, b.value(2));
1148 }
1149
1150 #[test]
1151 fn test_temporal_array_date32_day() {
1152 let a: PrimitiveArray<Date32Type> = vec![Some(0), None, Some(31)].into();
1153
1154 let b = day(&a).unwrap();
1155 assert_eq!(1, b.value(0));
1156 assert!(!b.is_valid(1));
1157 assert_eq!(1, b.value(2));
1158 }
1159
1160 #[test]
1161 fn test_temporal_array_date64_doy() {
1162 let a: PrimitiveArray<Date64Type> = vec![
1166 Some(1483228800000),
1167 Some(1514764800000),
1168 None,
1169 Some(1550636625000),
1170 ]
1171 .into();
1172
1173 let b = doy(&a).unwrap();
1174 assert_eq!(1, b.value(0));
1175 assert_eq!(1, b.value(1));
1176 assert!(!b.is_valid(2));
1177 assert_eq!(51, b.value(3));
1178 }
1179
1180 #[test]
1181 fn test_temporal_array_timestamp_micro_year() {
1182 let a: TimestampMicrosecondArray =
1183 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1184
1185 let b = year(&a).unwrap();
1186 assert_eq!(2021, b.value(0));
1187 assert!(!b.is_valid(1));
1188 assert_eq!(2024, b.value(2));
1189 }
1190
1191 #[test]
1192 fn test_temporal_array_date64_minute() {
1193 let a: PrimitiveArray<Date64Type> =
1194 vec![Some(1514764800000), None, Some(1550636625000)].into();
1195
1196 let b = minute(&a).unwrap();
1197 assert_eq!(0, b.value(0));
1198 assert!(!b.is_valid(1));
1199 assert_eq!(23, b.value(2));
1200 }
1201
1202 #[test]
1203 fn test_temporal_array_timestamp_micro_minute() {
1204 let a: TimestampMicrosecondArray =
1205 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1206
1207 let b = minute(&a).unwrap();
1208 assert_eq!(57, b.value(0));
1209 assert!(!b.is_valid(1));
1210 assert_eq!(44, b.value(2));
1211 }
1212
1213 #[test]
1214 fn test_temporal_array_date32_week() {
1215 let a: PrimitiveArray<Date32Type> = vec![Some(0), None, Some(7)].into();
1216
1217 let b = week(&a).unwrap();
1218 assert_eq!(1, b.value(0));
1219 assert!(!b.is_valid(1));
1220 assert_eq!(2, b.value(2));
1221 }
1222
1223 #[test]
1224 fn test_temporal_array_date64_week() {
1225 let a: PrimitiveArray<Date64Type> = vec![
1228 Some(1646116175000),
1229 None,
1230 Some(1641171600000),
1231 Some(1640998800000),
1232 ]
1233 .into();
1234
1235 let b = week(&a).unwrap();
1236 assert_eq!(9, b.value(0));
1237 assert!(!b.is_valid(1));
1238 assert_eq!(1, b.value(2));
1239 assert_eq!(52, b.value(3));
1240 }
1241
1242 #[test]
1243 fn test_temporal_array_timestamp_micro_week() {
1244 let a: TimestampMicrosecondArray =
1247 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1248
1249 let b = week(&a).unwrap();
1250 assert_eq!(4, b.value(0));
1251 assert!(!b.is_valid(1));
1252 assert_eq!(30, b.value(2));
1253 }
1254
1255 #[test]
1256 fn test_temporal_array_date64_second() {
1257 let a: PrimitiveArray<Date64Type> =
1258 vec![Some(1514764800000), None, Some(1550636625000)].into();
1259
1260 let b = second(&a).unwrap();
1261 assert_eq!(0, b.value(0));
1262 assert!(!b.is_valid(1));
1263 assert_eq!(45, b.value(2));
1264 }
1265
1266 #[test]
1267 fn test_temporal_array_timestamp_micro_second() {
1268 let a: TimestampMicrosecondArray =
1269 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1270
1271 let b = second(&a).unwrap();
1272 assert_eq!(27, b.value(0));
1273 assert!(!b.is_valid(1));
1274 assert_eq!(7, b.value(2));
1275 }
1276
1277 #[test]
1278 fn test_temporal_array_timestamp_second_with_timezone() {
1279 let a = TimestampSecondArray::from(vec![10, 20]).with_timezone("+00:00".to_string());
1280 let b = second(&a).unwrap();
1281 assert_eq!(10, b.value(0));
1282 assert_eq!(20, b.value(1));
1283 }
1284
1285 #[test]
1286 fn test_temporal_array_timestamp_minute_with_timezone() {
1287 let a = TimestampSecondArray::from(vec![0, 60]).with_timezone("+00:50".to_string());
1288 let b = minute(&a).unwrap();
1289 assert_eq!(50, b.value(0));
1290 assert_eq!(51, b.value(1));
1291 }
1292
1293 #[test]
1294 fn test_temporal_array_timestamp_minute_with_negative_timezone() {
1295 let a = TimestampSecondArray::from(vec![60 * 55]).with_timezone("-00:50".to_string());
1296 let b = minute(&a).unwrap();
1297 assert_eq!(5, b.value(0));
1298 }
1299
1300 #[test]
1301 fn test_temporal_array_timestamp_hour_with_timezone() {
1302 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+01:00".to_string());
1303 let b = hour(&a).unwrap();
1304 assert_eq!(11, b.value(0));
1305 }
1306
1307 #[test]
1308 fn test_temporal_array_timestamp_hour_with_timezone_without_colon() {
1309 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+0100".to_string());
1310 let b = hour(&a).unwrap();
1311 assert_eq!(11, b.value(0));
1312 }
1313
1314 #[test]
1315 fn test_temporal_array_timestamp_hour_with_timezone_without_minutes() {
1316 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+01".to_string());
1317 let b = hour(&a).unwrap();
1318 assert_eq!(11, b.value(0));
1319 }
1320
1321 #[test]
1322 fn test_temporal_array_timestamp_hour_with_timezone_without_initial_sign() {
1323 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("0100".to_string());
1324 let err = hour(&a).unwrap_err().to_string();
1325 assert!(err.contains("Invalid timezone"), "{}", err);
1326 }
1327
1328 #[test]
1329 fn test_temporal_array_timestamp_hour_with_timezone_with_only_colon() {
1330 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("01:00".to_string());
1331 let err = hour(&a).unwrap_err().to_string();
1332 assert!(err.contains("Invalid timezone"), "{}", err);
1333 }
1334
1335 #[test]
1336 fn test_temporal_array_timestamp_week_without_timezone() {
1337 let a = TimestampSecondArray::from(vec![0, 86400 * 4, 86400 * 4 - 1]);
1341 let b = week(&a).unwrap();
1342 assert_eq!(1, b.value(0));
1343 assert_eq!(2, b.value(1));
1344 assert_eq!(1, b.value(2));
1345 }
1346
1347 #[test]
1348 fn test_temporal_array_timestamp_week_with_timezone() {
1349 let a = TimestampSecondArray::from(vec![0, 86400 * 4, 86400 * 4 - 1])
1353 .with_timezone("+01:00".to_string());
1354 let b = week(&a).unwrap();
1355 assert_eq!(1, b.value(0));
1356 assert_eq!(2, b.value(1));
1357 assert_eq!(2, b.value(2));
1358 }
1359
1360 #[test]
1361 fn test_hour_minute_second_dictionary_array() {
1362 let a = TimestampSecondArray::from(vec![
1363 60 * 60 * 10 + 61,
1364 60 * 60 * 20 + 122,
1365 60 * 60 * 30 + 183,
1366 ])
1367 .with_timezone("+01:00".to_string());
1368
1369 let keys = Int8Array::from_iter_values([0_i8, 0, 1, 2, 1]);
1370 let dict = DictionaryArray::try_new(keys.clone(), Arc::new(a)).unwrap();
1371
1372 let b = hour_dyn(&dict).unwrap();
1373
1374 let expected_dict =
1375 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![11, 21, 7])));
1376 let expected = Arc::new(expected_dict) as ArrayRef;
1377 assert_eq!(&expected, &b);
1378
1379 let b = date_part(&dict, DatePart::Minute).unwrap();
1380
1381 let b_old = minute_dyn(&dict).unwrap();
1382
1383 let expected_dict =
1384 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 2, 3])));
1385 let expected = Arc::new(expected_dict) as ArrayRef;
1386 assert_eq!(&expected, &b);
1387 assert_eq!(&expected, &b_old);
1388
1389 let b = date_part(&dict, DatePart::Second).unwrap();
1390
1391 let b_old = second_dyn(&dict).unwrap();
1392
1393 let expected_dict =
1394 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 2, 3])));
1395 let expected = Arc::new(expected_dict) as ArrayRef;
1396 assert_eq!(&expected, &b);
1397 assert_eq!(&expected, &b_old);
1398
1399 let b = date_part(&dict, DatePart::Nanosecond).unwrap();
1400
1401 let expected_dict =
1402 DictionaryArray::new(keys, Arc::new(Int32Array::from(vec![0, 0, 0, 0, 0])));
1403 let expected = Arc::new(expected_dict) as ArrayRef;
1404 assert_eq!(&expected, &b);
1405 }
1406
1407 #[test]
1408 fn test_year_dictionary_array() {
1409 let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1550636625000)].into();
1410
1411 let keys = Int8Array::from_iter_values([0_i8, 1, 1, 0]);
1412 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1413
1414 let b = year_dyn(&dict).unwrap();
1415
1416 let expected_dict = DictionaryArray::new(
1417 keys,
1418 Arc::new(Int32Array::from(vec![2018, 2019, 2019, 2018])),
1419 );
1420 let expected = Arc::new(expected_dict) as ArrayRef;
1421 assert_eq!(&expected, &b);
1422 }
1423
1424 #[test]
1425 fn test_quarter_month_dictionary_array() {
1426 let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1566275025000)].into();
1429
1430 let keys = Int8Array::from_iter_values([0_i8, 1, 1, 0]);
1431 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1432
1433 let b = quarter_dyn(&dict).unwrap();
1434
1435 let expected =
1436 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 3, 3, 1])));
1437 assert_eq!(b.as_ref(), &expected);
1438
1439 let b = month_dyn(&dict).unwrap();
1440
1441 let expected = DictionaryArray::new(keys, Arc::new(Int32Array::from(vec![1, 8, 8, 1])));
1442 assert_eq!(b.as_ref(), &expected);
1443 }
1444
1445 #[test]
1446 fn test_num_days_from_monday_sunday_day_doy_week_dictionary_array() {
1447 let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1550636625000)].into();
1450
1451 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1), Some(0), None]);
1452 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1453
1454 let b = num_days_from_monday_dyn(&dict).unwrap();
1455
1456 let a = Int32Array::from(vec![Some(0), Some(2), Some(2), Some(0), None]);
1457 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1458 assert_eq!(b.as_ref(), &expected);
1459
1460 let b = num_days_from_sunday_dyn(&dict).unwrap();
1461
1462 let a = Int32Array::from(vec![Some(1), Some(3), Some(3), Some(1), None]);
1463 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1464 assert_eq!(b.as_ref(), &expected);
1465
1466 let b = day_dyn(&dict).unwrap();
1467
1468 let a = Int32Array::from(vec![Some(1), Some(20), Some(20), Some(1), None]);
1469 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1470 assert_eq!(b.as_ref(), &expected);
1471
1472 let b = doy_dyn(&dict).unwrap();
1473
1474 let a = Int32Array::from(vec![Some(1), Some(51), Some(51), Some(1), None]);
1475 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1476 assert_eq!(b.as_ref(), &expected);
1477
1478 let b = week_dyn(&dict).unwrap();
1479
1480 let a = Int32Array::from(vec![Some(1), Some(8), Some(8), Some(1), None]);
1481 let expected = DictionaryArray::new(keys, Arc::new(a));
1482 assert_eq!(b.as_ref(), &expected);
1483 }
1484
1485 #[test]
1486 fn test_temporal_array_date64_nanosecond() {
1487 let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
1494
1495 let b = nanosecond(&a).unwrap();
1496 assert!(!b.is_valid(0));
1497 assert_eq!(453_000_000, b.value(1));
1498
1499 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
1500 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1501 let b = nanosecond_dyn(&dict).unwrap();
1502
1503 let a = Int32Array::from(vec![None, Some(453_000_000)]);
1504 let expected_dict = DictionaryArray::new(keys, Arc::new(a));
1505 let expected = Arc::new(expected_dict) as ArrayRef;
1506 assert_eq!(&expected, &b);
1507 }
1508
1509 #[test]
1510 fn test_temporal_array_date64_microsecond() {
1511 let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
1512
1513 let b = microsecond(&a).unwrap();
1514 assert!(!b.is_valid(0));
1515 assert_eq!(453_000, b.value(1));
1516
1517 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
1518 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1519 let b = microsecond_dyn(&dict).unwrap();
1520
1521 let a = Int32Array::from(vec![None, Some(453_000)]);
1522 let expected_dict = DictionaryArray::new(keys, Arc::new(a));
1523 let expected = Arc::new(expected_dict) as ArrayRef;
1524 assert_eq!(&expected, &b);
1525 }
1526
1527 #[test]
1528 fn test_temporal_array_date64_millisecond() {
1529 let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
1530
1531 let b = millisecond(&a).unwrap();
1532 assert!(!b.is_valid(0));
1533 assert_eq!(453, b.value(1));
1534
1535 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
1536 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1537 let b = millisecond_dyn(&dict).unwrap();
1538
1539 let a = Int32Array::from(vec![None, Some(453)]);
1540 let expected_dict = DictionaryArray::new(keys, Arc::new(a));
1541 let expected = Arc::new(expected_dict) as ArrayRef;
1542 assert_eq!(&expected, &b);
1543 }
1544
1545 #[test]
1546 fn test_temporal_array_time64_nanoseconds() {
1547 let input: Time64NanosecondArray = vec![Some(84_770_123_456_789)].into();
1549
1550 let actual = date_part(&input, DatePart::Hour).unwrap();
1551 let actual = actual.as_primitive::<Int32Type>();
1552 assert_eq!(23, actual.value(0));
1553
1554 let actual = date_part(&input, DatePart::Minute).unwrap();
1555 let actual = actual.as_primitive::<Int32Type>();
1556 assert_eq!(32, actual.value(0));
1557
1558 let actual = date_part(&input, DatePart::Second).unwrap();
1559 let actual = actual.as_primitive::<Int32Type>();
1560 assert_eq!(50, actual.value(0));
1561
1562 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1563 let actual = actual.as_primitive::<Int32Type>();
1564 assert_eq!(123, actual.value(0));
1565
1566 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1567 let actual = actual.as_primitive::<Int32Type>();
1568 assert_eq!(123_456, actual.value(0));
1569
1570 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1571 let actual = actual.as_primitive::<Int32Type>();
1572 assert_eq!(123_456_789, actual.value(0));
1573
1574 let input: Time64NanosecondArray = vec![
1576 Some(-1),
1577 Some(86_400_000_000_000),
1578 Some(86_401_000_000_000),
1579 None,
1580 ]
1581 .into();
1582 let actual = date_part(&input, DatePart::Hour).unwrap();
1583 let actual = actual.as_primitive::<Int32Type>();
1584 let expected: Int32Array = vec![None, None, None, None].into();
1585 assert_eq!(&expected, actual);
1586 }
1587
1588 #[test]
1589 fn test_temporal_array_time64_microseconds() {
1590 let input: Time64MicrosecondArray = vec![Some(84_770_123_456)].into();
1592
1593 let actual = date_part(&input, DatePart::Hour).unwrap();
1594 let actual = actual.as_primitive::<Int32Type>();
1595 assert_eq!(23, actual.value(0));
1596
1597 let actual = date_part(&input, DatePart::Minute).unwrap();
1598 let actual = actual.as_primitive::<Int32Type>();
1599 assert_eq!(32, actual.value(0));
1600
1601 let actual = date_part(&input, DatePart::Second).unwrap();
1602 let actual = actual.as_primitive::<Int32Type>();
1603 assert_eq!(50, actual.value(0));
1604
1605 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1606 let actual = actual.as_primitive::<Int32Type>();
1607 assert_eq!(123, actual.value(0));
1608
1609 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1610 let actual = actual.as_primitive::<Int32Type>();
1611 assert_eq!(123_456, actual.value(0));
1612
1613 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1614 let actual = actual.as_primitive::<Int32Type>();
1615 assert_eq!(123_456_000, actual.value(0));
1616
1617 let input: Time64MicrosecondArray =
1619 vec![Some(-1), Some(86_400_000_000), Some(86_401_000_000), None].into();
1620 let actual = date_part(&input, DatePart::Hour).unwrap();
1621 let actual = actual.as_primitive::<Int32Type>();
1622 let expected: Int32Array = vec![None, None, None, None].into();
1623 assert_eq!(&expected, actual);
1624 }
1625
1626 #[test]
1627 fn test_temporal_array_time32_milliseconds() {
1628 let input: Time32MillisecondArray = vec![Some(84_770_123)].into();
1630
1631 let actual = date_part(&input, DatePart::Hour).unwrap();
1632 let actual = actual.as_primitive::<Int32Type>();
1633 assert_eq!(23, actual.value(0));
1634
1635 let actual = date_part(&input, DatePart::Minute).unwrap();
1636 let actual = actual.as_primitive::<Int32Type>();
1637 assert_eq!(32, actual.value(0));
1638
1639 let actual = date_part(&input, DatePart::Second).unwrap();
1640 let actual = actual.as_primitive::<Int32Type>();
1641 assert_eq!(50, actual.value(0));
1642
1643 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1644 let actual = actual.as_primitive::<Int32Type>();
1645 assert_eq!(123, actual.value(0));
1646
1647 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1648 let actual = actual.as_primitive::<Int32Type>();
1649 assert_eq!(123_000, actual.value(0));
1650
1651 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1652 let actual = actual.as_primitive::<Int32Type>();
1653 assert_eq!(123_000_000, actual.value(0));
1654
1655 let input: Time32MillisecondArray =
1657 vec![Some(-1), Some(86_400_000), Some(86_401_000), None].into();
1658 let actual = date_part(&input, DatePart::Hour).unwrap();
1659 let actual = actual.as_primitive::<Int32Type>();
1660 let expected: Int32Array = vec![None, None, None, None].into();
1661 assert_eq!(&expected, actual);
1662 }
1663
1664 #[test]
1665 fn test_temporal_array_time32_seconds() {
1666 let input: Time32SecondArray = vec![84_770].into();
1668
1669 let actual = date_part(&input, DatePart::Hour).unwrap();
1670 let actual = actual.as_primitive::<Int32Type>();
1671 assert_eq!(23, actual.value(0));
1672
1673 let actual = date_part(&input, DatePart::Minute).unwrap();
1674 let actual = actual.as_primitive::<Int32Type>();
1675 assert_eq!(32, actual.value(0));
1676
1677 let actual = date_part(&input, DatePart::Second).unwrap();
1678 let actual = actual.as_primitive::<Int32Type>();
1679 assert_eq!(50, actual.value(0));
1680
1681 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1682 let actual = actual.as_primitive::<Int32Type>();
1683 assert_eq!(0, actual.value(0));
1684
1685 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1686 let actual = actual.as_primitive::<Int32Type>();
1687 assert_eq!(0, actual.value(0));
1688
1689 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1690 let actual = actual.as_primitive::<Int32Type>();
1691 assert_eq!(0, actual.value(0));
1692
1693 let input: Time32SecondArray = vec![Some(-1), Some(86_400), Some(86_401), None].into();
1695 let actual = date_part(&input, DatePart::Hour).unwrap();
1696 let actual = actual.as_primitive::<Int32Type>();
1697 let expected: Int32Array = vec![None, None, None, None].into();
1698 assert_eq!(&expected, actual);
1699 }
1700
1701 #[test]
1702 fn test_temporal_array_time_invalid_parts() {
1703 fn ensure_returns_error(array: &dyn Array) {
1704 let invalid_parts = [
1705 DatePart::Quarter,
1706 DatePart::Year,
1707 DatePart::Month,
1708 DatePart::Week,
1709 DatePart::Day,
1710 DatePart::DayOfWeekSunday0,
1711 DatePart::DayOfWeekMonday0,
1712 DatePart::DayOfYear,
1713 ];
1714
1715 for part in invalid_parts {
1716 let err = date_part(array, part).unwrap_err();
1717 let expected = format!(
1718 "Compute error: {part} does not support: {}",
1719 array.data_type()
1720 );
1721 assert_eq!(expected, err.to_string());
1722 }
1723 }
1724
1725 ensure_returns_error(&Time32SecondArray::from(vec![0]));
1726 ensure_returns_error(&Time32MillisecondArray::from(vec![0]));
1727 ensure_returns_error(&Time64MicrosecondArray::from(vec![0]));
1728 ensure_returns_error(&Time64NanosecondArray::from(vec![0]));
1729 }
1730
1731 #[test]
1732 fn test_interval_year_month_array() {
1733 let input: IntervalYearMonthArray = vec![0, 5, 24].into();
1734
1735 let actual = date_part(&input, DatePart::Year).unwrap();
1736 let actual = actual.as_primitive::<Int32Type>();
1737 assert_eq!(0, actual.value(0));
1738 assert_eq!(0, actual.value(1));
1739 assert_eq!(2, actual.value(2));
1740
1741 let actual = date_part(&input, DatePart::Month).unwrap();
1742 let actual = actual.as_primitive::<Int32Type>();
1743 assert_eq!(0, actual.value(0));
1744 assert_eq!(5, actual.value(1));
1745 assert_eq!(0, actual.value(2));
1746
1747 assert!(date_part(&input, DatePart::Day).is_err());
1748 assert!(date_part(&input, DatePart::Week).is_err());
1749 }
1750
1751 #[test]
1754 fn test_interval_day_time_array() {
1755 let input: IntervalDayTimeArray = vec![
1756 IntervalDayTime::ZERO,
1757 IntervalDayTime::new(10, 42),
1758 IntervalDayTime::new(10, 1042),
1759 IntervalDayTime::new(10, MILLISECONDS_IN_DAY as i32 + 1),
1760 ]
1761 .into();
1762
1763 let actual = date_part(&input, DatePart::Day).unwrap();
1765 let actual = actual.as_primitive::<Int32Type>();
1766 assert_eq!(0, actual.value(0));
1767 assert_eq!(10, actual.value(1));
1768 assert_eq!(10, actual.value(2));
1769 assert_eq!(10, actual.value(3));
1770
1771 let actual = date_part(&input, DatePart::Week).unwrap();
1772 let actual = actual.as_primitive::<Int32Type>();
1773 assert_eq!(0, actual.value(0));
1774 assert_eq!(1, actual.value(1));
1775 assert_eq!(1, actual.value(2));
1776 assert_eq!(1, actual.value(3));
1777
1778 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1780 let actual = actual.as_primitive::<Int32Type>();
1781 assert_eq!(0, actual.value(0));
1782 assert_eq!(42_000_000, actual.value(1));
1783 assert_eq!(1_042_000_000, actual.value(2));
1784 assert_eq!(0, actual.value(3));
1786
1787 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1788 let actual = actual.as_primitive::<Int32Type>();
1789 assert_eq!(0, actual.value(0));
1790 assert_eq!(42_000, actual.value(1));
1791 assert_eq!(1_042_000, actual.value(2));
1792 assert_eq!(0, actual.value(3));
1794
1795 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1796 let actual = actual.as_primitive::<Int32Type>();
1797 assert_eq!(0, actual.value(0));
1798 assert_eq!(42, actual.value(1));
1799 assert_eq!(1042, actual.value(2));
1800 assert_eq!(MILLISECONDS_IN_DAY as i32 + 1, actual.value(3));
1801
1802 let actual = date_part(&input, DatePart::Second).unwrap();
1803 let actual = actual.as_primitive::<Int32Type>();
1804 assert_eq!(0, actual.value(0));
1805 assert_eq!(0, actual.value(1));
1806 assert_eq!(1, actual.value(2));
1807 assert_eq!(24 * 60 * 60, actual.value(3));
1808
1809 let actual = date_part(&input, DatePart::Minute).unwrap();
1810 let actual = actual.as_primitive::<Int32Type>();
1811 assert_eq!(0, actual.value(0));
1812 assert_eq!(0, actual.value(1));
1813 assert_eq!(0, actual.value(2));
1814 assert_eq!(24 * 60, actual.value(3));
1815
1816 let actual = date_part(&input, DatePart::Hour).unwrap();
1817 let actual = actual.as_primitive::<Int32Type>();
1818 assert_eq!(0, actual.value(0));
1819 assert_eq!(0, actual.value(1));
1820 assert_eq!(0, actual.value(2));
1821 assert_eq!(24, actual.value(3));
1822
1823 assert!(date_part(&input, DatePart::Month).is_err());
1825 assert!(date_part(&input, DatePart::Year).is_err());
1826 }
1827
1828 #[test]
1831 fn test_interval_month_day_nano_array() {
1832 let input: IntervalMonthDayNanoArray = vec![
1833 IntervalMonthDayNano::ZERO,
1834 IntervalMonthDayNano::new(5, 10, 42),
1835 IntervalMonthDayNano::new(16, 35, MILLISECONDS_IN_DAY * 1_000_000 + 1),
1836 ]
1837 .into();
1838
1839 let actual = date_part(&input, DatePart::Year).unwrap();
1841 let actual = actual.as_primitive::<Int32Type>();
1842 assert_eq!(0, actual.value(0));
1843 assert_eq!(0, actual.value(1));
1844 assert_eq!(1, actual.value(2));
1845
1846 let actual = date_part(&input, DatePart::Month).unwrap();
1847 let actual = actual.as_primitive::<Int32Type>();
1848 assert_eq!(0, actual.value(0));
1849 assert_eq!(5, actual.value(1));
1850 assert_eq!(16, actual.value(2));
1851
1852 let actual = date_part(&input, DatePart::Week).unwrap();
1854 let actual = actual.as_primitive::<Int32Type>();
1855 assert_eq!(0, actual.value(0));
1856 assert_eq!(1, actual.value(1));
1857 assert_eq!(5, actual.value(2));
1858
1859 let actual = date_part(&input, DatePart::Day).unwrap();
1860 let actual = actual.as_primitive::<Int32Type>();
1861 assert_eq!(0, actual.value(0));
1862 assert_eq!(10, actual.value(1));
1863 assert_eq!(35, actual.value(2));
1864
1865 let actual = date_part(&input, DatePart::Hour).unwrap();
1867 let actual = actual.as_primitive::<Int32Type>();
1868 assert_eq!(0, actual.value(0));
1869 assert_eq!(0, actual.value(1));
1870 assert_eq!(24, actual.value(2));
1871
1872 let actual = date_part(&input, DatePart::Minute).unwrap();
1873 let actual = actual.as_primitive::<Int32Type>();
1874 assert_eq!(0, actual.value(0));
1875 assert_eq!(0, actual.value(1));
1876 assert_eq!(24 * 60, actual.value(2));
1877
1878 let actual = date_part(&input, DatePart::Second).unwrap();
1879 let actual = actual.as_primitive::<Int32Type>();
1880 assert_eq!(0, actual.value(0));
1881 assert_eq!(0, actual.value(1));
1882 assert_eq!(24 * 60 * 60, actual.value(2));
1883
1884 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1885 let actual = actual.as_primitive::<Int32Type>();
1886 assert_eq!(0, actual.value(0));
1887 assert_eq!(0, actual.value(1));
1888 assert_eq!(24 * 60 * 60 * 1_000, actual.value(2));
1889
1890 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1891 let actual = actual.as_primitive::<Int32Type>();
1892 assert_eq!(0, actual.value(0));
1893 assert_eq!(0, actual.value(1));
1894 assert_eq!(0, actual.value(2));
1896
1897 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1898 let actual = actual.as_primitive::<Int32Type>();
1899 assert_eq!(0, actual.value(0));
1900 assert_eq!(42, actual.value(1));
1901 assert_eq!(0, actual.value(2));
1903 }
1904
1905 #[test]
1906 fn test_interval_array_invalid_parts() {
1907 fn ensure_returns_error(array: &dyn Array) {
1908 let invalid_parts = [
1909 DatePart::Quarter,
1910 DatePart::DayOfWeekSunday0,
1911 DatePart::DayOfWeekMonday0,
1912 DatePart::DayOfYear,
1913 ];
1914
1915 for part in invalid_parts {
1916 let err = date_part(array, part).unwrap_err();
1917 let expected = format!(
1918 "Compute error: {part} does not support: {}",
1919 array.data_type()
1920 );
1921 assert_eq!(expected, err.to_string());
1922 }
1923 }
1924
1925 ensure_returns_error(&IntervalYearMonthArray::from(vec![0]));
1926 ensure_returns_error(&IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]));
1927 ensure_returns_error(&IntervalMonthDayNanoArray::from(vec![
1928 IntervalMonthDayNano::ZERO,
1929 ]));
1930 }
1931
1932 #[test]
1933 fn test_duration_second() {
1934 let input: DurationSecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
1935
1936 let actual = date_part(&input, DatePart::Second).unwrap();
1937 let actual = actual.as_primitive::<Int32Type>();
1938 assert_eq!(0, actual.value(0));
1939 assert_eq!(42, actual.value(1));
1940 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
1941
1942 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1943 let actual = actual.as_primitive::<Int32Type>();
1944 assert_eq!(0, actual.value(0));
1945 assert_eq!(42_000, actual.value(1));
1946 assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
1947
1948 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1949 let actual = actual.as_primitive::<Int32Type>();
1950 assert_eq!(0, actual.value(0));
1951 assert_eq!(42_000_000, actual.value(1));
1952 assert_eq!(0, actual.value(2));
1953
1954 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1955 let actual = actual.as_primitive::<Int32Type>();
1956 assert_eq!(0, actual.value(0));
1957 assert_eq!(0, actual.value(1));
1958 assert_eq!(0, actual.value(2));
1959 }
1960
1961 #[test]
1962 fn test_duration_millisecond() {
1963 let input: DurationMillisecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
1964
1965 let actual = date_part(&input, DatePart::Second).unwrap();
1966 let actual = actual.as_primitive::<Int32Type>();
1967 assert_eq!(0, actual.value(0));
1968 assert_eq!(0, actual.value(1));
1969 assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
1970
1971 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1972 let actual = actual.as_primitive::<Int32Type>();
1973 assert_eq!(0, actual.value(0));
1974 assert_eq!(42, actual.value(1));
1975 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
1976
1977 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1978 let actual = actual.as_primitive::<Int32Type>();
1979 assert_eq!(0, actual.value(0));
1980 assert_eq!(42_000, actual.value(1));
1981 assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
1982
1983 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1984 let actual = actual.as_primitive::<Int32Type>();
1985 assert_eq!(0, actual.value(0));
1986 assert_eq!(42_000_000, actual.value(1));
1987 assert_eq!(0, actual.value(2));
1988 }
1989
1990 #[test]
1991 fn test_duration_microsecond() {
1992 let input: DurationMicrosecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
1993
1994 let actual = date_part(&input, DatePart::Second).unwrap();
1995 let actual = actual.as_primitive::<Int32Type>();
1996 assert_eq!(0, actual.value(0));
1997 assert_eq!(0, actual.value(1));
1998 assert_eq!(0, actual.value(2));
1999
2000 let actual = date_part(&input, DatePart::Millisecond).unwrap();
2001 let actual = actual.as_primitive::<Int32Type>();
2002 assert_eq!(0, actual.value(0));
2003 assert_eq!(0, actual.value(1));
2004 assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
2005
2006 let actual = date_part(&input, DatePart::Microsecond).unwrap();
2007 let actual = actual.as_primitive::<Int32Type>();
2008 assert_eq!(0, actual.value(0));
2009 assert_eq!(42, actual.value(1));
2010 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
2011
2012 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
2013 let actual = actual.as_primitive::<Int32Type>();
2014 assert_eq!(0, actual.value(0));
2015 assert_eq!(42_000, actual.value(1));
2016 assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
2017 }
2018
2019 #[test]
2020 fn test_duration_nanosecond() {
2021 let input: DurationNanosecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
2022
2023 let actual = date_part(&input, DatePart::Second).unwrap();
2024 let actual = actual.as_primitive::<Int32Type>();
2025 assert_eq!(0, actual.value(0));
2026 assert_eq!(0, actual.value(1));
2027 assert_eq!(0, actual.value(2));
2028
2029 let actual = date_part(&input, DatePart::Millisecond).unwrap();
2030 let actual = actual.as_primitive::<Int32Type>();
2031 assert_eq!(0, actual.value(0));
2032 assert_eq!(0, actual.value(1));
2033 assert_eq!(0, actual.value(2));
2034
2035 let actual = date_part(&input, DatePart::Microsecond).unwrap();
2036 let actual = actual.as_primitive::<Int32Type>();
2037 assert_eq!(0, actual.value(0));
2038 assert_eq!(0, actual.value(1));
2039 assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
2040
2041 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
2042 let actual = actual.as_primitive::<Int32Type>();
2043 assert_eq!(0, actual.value(0));
2044 assert_eq!(42, actual.value(1));
2045 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
2046 }
2047
2048 #[test]
2049 fn test_duration_invalid_parts() {
2050 fn ensure_returns_error(array: &dyn Array) {
2051 let invalid_parts = [
2052 DatePart::Year,
2053 DatePart::Quarter,
2054 DatePart::Month,
2055 DatePart::DayOfWeekSunday0,
2056 DatePart::DayOfWeekMonday0,
2057 DatePart::DayOfYear,
2058 ];
2059
2060 for part in invalid_parts {
2061 let err = date_part(array, part).unwrap_err();
2062 let expected = format!(
2063 "Compute error: {part} does not support: {}",
2064 array.data_type()
2065 );
2066 assert_eq!(expected, err.to_string());
2067 }
2068 }
2069
2070 ensure_returns_error(&DurationSecondArray::from(vec![0]));
2071 ensure_returns_error(&DurationMillisecondArray::from(vec![0]));
2072 ensure_returns_error(&DurationMicrosecondArray::from(vec![0]));
2073 ensure_returns_error(&DurationNanosecondArray::from(vec![0]));
2074 }
2075}