1use std::sync::Arc;
19
20use arrow_arith::arity::binary;
21use arrow_arith::temporal::{DatePart, date_part};
22use arrow_array::types::Date32Type;
23use arrow_array::{
24 Array, ArrayRef, Date32Array, Int32Array, TimestampMicrosecondArray, TimestampNanosecondArray,
25};
26use arrow_schema::{DataType, TimeUnit};
27use chrono::{DateTime, Datelike, Duration};
28
29use super::TransformFunction;
30use crate::spec::{Datum, PrimitiveLiteral, PrimitiveType};
31use crate::{Error, ErrorKind, Result};
32
33const MICROSECONDS_PER_HOUR: i64 = 3_600_000_000;
35const NANOSECONDS_PER_HOUR: i64 = 3_600_000_000_000;
37const UNIX_EPOCH_YEAR: i32 = 1970;
39const MICROS_PER_SECOND: i64 = 1_000_000;
41const NANOS_PER_SECOND: i64 = 1_000_000_000;
43
44#[derive(Debug)]
46pub struct Year;
47
48impl Year {
49 #[inline]
50 fn timestamp_to_year_micros(timestamp: i64) -> Result<i32> {
51 Ok(DateTime::from_timestamp_micros(timestamp)
52 .ok_or_else(|| {
53 Error::new(
54 ErrorKind::DataInvalid,
55 "Fail to convert timestamp to date in year transform",
56 )
57 })?
58 .year()
59 - UNIX_EPOCH_YEAR)
60 }
61
62 #[inline]
63 fn timestamp_to_year_nanos(timestamp: i64) -> Result<i32> {
64 Ok(DateTime::from_timestamp_nanos(timestamp).year() - UNIX_EPOCH_YEAR)
65 }
66}
67
68impl TransformFunction for Year {
69 fn transform(&self, input: ArrayRef) -> Result<ArrayRef> {
70 let array = date_part(&input, DatePart::Year)
71 .map_err(|err| Error::new(ErrorKind::Unexpected, format!("{err}")))?;
72 Ok(Arc::<Int32Array>::new(
73 array
74 .as_any()
75 .downcast_ref::<Int32Array>()
76 .unwrap()
77 .unary(|v| v - UNIX_EPOCH_YEAR),
78 ))
79 }
80
81 fn transform_literal(&self, input: &crate::spec::Datum) -> Result<Option<crate::spec::Datum>> {
82 let val = match (input.data_type(), input.literal()) {
83 (PrimitiveType::Date, PrimitiveLiteral::Int(v)) => {
84 Date32Type::to_naive_date(*v).year() - UNIX_EPOCH_YEAR
85 }
86 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) => {
87 Self::timestamp_to_year_micros(*v)?
88 }
89 (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) => {
90 Self::timestamp_to_year_micros(*v)?
91 }
92 (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
93 Self::timestamp_to_year_nanos(*v)?
94 }
95 (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
96 Self::timestamp_to_year_nanos(*v)?
97 }
98 _ => {
99 return Err(crate::Error::new(
100 crate::ErrorKind::FeatureUnsupported,
101 format!(
102 "Unsupported data type for year transform: {:?}",
103 input.data_type()
104 ),
105 ));
106 }
107 };
108 Ok(Some(Datum::int(val)))
109 }
110}
111
112#[derive(Debug)]
114pub struct Month;
115
116impl Month {
117 #[inline]
118 fn timestamp_to_month_micros(timestamp: i64) -> Result<i32> {
119 let date = DateTime::from_timestamp_micros(timestamp).ok_or_else(|| {
124 Error::new(
125 ErrorKind::DataInvalid,
126 "Fail to convert timestamp to date in month transform",
127 )
128 })?;
129 let unix_epoch_date = DateTime::from_timestamp_micros(0)
130 .expect("0 timestamp from unix epoch should be valid");
131 if date > unix_epoch_date {
132 Ok((date.month0() as i32) + 12 * (date.year() - UNIX_EPOCH_YEAR))
133 } else {
134 let delta = (12 - date.month0() as i32) + 12 * (UNIX_EPOCH_YEAR - date.year() - 1);
135 Ok(-delta)
136 }
137 }
138
139 #[inline]
140 fn timestamp_to_month_nanos(timestamp: i64) -> Result<i32> {
141 let date = DateTime::from_timestamp_nanos(timestamp);
146 let unix_epoch_date = DateTime::from_timestamp_nanos(0);
147 if date > unix_epoch_date {
148 Ok((date.month0() as i32) + 12 * (date.year() - UNIX_EPOCH_YEAR))
149 } else {
150 let delta = (12 - date.month0() as i32) + 12 * (UNIX_EPOCH_YEAR - date.year() - 1);
151 Ok(-delta)
152 }
153 }
154}
155
156impl TransformFunction for Month {
157 fn transform(&self, input: ArrayRef) -> Result<ArrayRef> {
158 let year_array = date_part(&input, DatePart::Year)
159 .map_err(|err| Error::new(ErrorKind::Unexpected, format!("{err}")))?;
160 let year_array: Int32Array = year_array
161 .as_any()
162 .downcast_ref::<Int32Array>()
163 .unwrap()
164 .unary(|v| 12 * (v - UNIX_EPOCH_YEAR));
165 let month_array = date_part(&input, DatePart::Month)
166 .map_err(|err| Error::new(ErrorKind::Unexpected, format!("{err}")))?;
167 Ok(Arc::<Int32Array>::new(
168 binary(
169 month_array.as_any().downcast_ref::<Int32Array>().unwrap(),
170 year_array.as_any().downcast_ref::<Int32Array>().unwrap(),
171 |a, b| a + b - 1,
173 )
174 .unwrap(),
175 ))
176 }
177
178 fn transform_literal(&self, input: &crate::spec::Datum) -> Result<Option<crate::spec::Datum>> {
179 let val = match (input.data_type(), input.literal()) {
180 (PrimitiveType::Date, PrimitiveLiteral::Int(v)) => {
181 (Date32Type::to_naive_date(*v).year() - UNIX_EPOCH_YEAR) * 12
182 + Date32Type::to_naive_date(*v).month0() as i32
183 }
184 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) => {
185 Self::timestamp_to_month_micros(*v)?
186 }
187 (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) => {
188 Self::timestamp_to_month_micros(*v)?
189 }
190 (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
191 Self::timestamp_to_month_nanos(*v)?
192 }
193 (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
194 Self::timestamp_to_month_nanos(*v)?
195 }
196 _ => {
197 return Err(crate::Error::new(
198 crate::ErrorKind::FeatureUnsupported,
199 format!(
200 "Unsupported data type for month transform: {:?}",
201 input.data_type()
202 ),
203 ));
204 }
205 };
206 Ok(Some(Datum::int(val)))
207 }
208}
209
210#[derive(Debug)]
212pub struct Day;
213
214impl Day {
215 #[inline]
216 fn day_timestamp_micro(v: i64) -> Result<i32> {
217 let secs = v / MICROS_PER_SECOND;
218
219 let (nanos, offset) = if v >= 0 {
220 let nanos = (v.rem_euclid(MICROS_PER_SECOND) * 1_000) as u32;
221 let offset = 0i64;
222 (nanos, offset)
223 } else {
224 let v = v + 1;
225 let nanos = (v.rem_euclid(MICROS_PER_SECOND) * 1_000) as u32;
226 let offset = 1i64;
227 (nanos, offset)
228 };
229
230 let delta = Duration::new(secs, nanos).ok_or_else(|| {
231 Error::new(
232 ErrorKind::DataInvalid,
233 format!("Failed to create 'TimeDelta' from seconds {secs} and nanos {nanos}"),
234 )
235 })?;
236
237 let days = (delta.num_days() - offset) as i32;
238
239 Ok(days)
240 }
241
242 fn day_timestamp_nano(v: i64) -> Result<i32> {
243 let secs = v / NANOS_PER_SECOND;
244
245 let (nanos, offset) = if v >= 0 {
246 let nanos = (v.rem_euclid(NANOS_PER_SECOND)) as u32;
247 let offset = 0i64;
248 (nanos, offset)
249 } else {
250 let v = v + 1;
251 let nanos = (v.rem_euclid(NANOS_PER_SECOND)) as u32;
252 let offset = 1i64;
253 (nanos, offset)
254 };
255
256 let delta = Duration::new(secs, nanos).ok_or_else(|| {
257 Error::new(
258 ErrorKind::DataInvalid,
259 format!("Failed to create 'TimeDelta' from seconds {secs} and nanos {nanos}"),
260 )
261 })?;
262
263 let days = (delta.num_days() - offset) as i32;
264
265 Ok(days)
266 }
267}
268
269impl TransformFunction for Day {
270 fn transform(&self, input: ArrayRef) -> Result<ArrayRef> {
271 let res: Date32Array = match input.data_type() {
272 DataType::Timestamp(TimeUnit::Microsecond, _) => input
273 .as_any()
274 .downcast_ref::<TimestampMicrosecondArray>()
275 .unwrap()
276 .try_unary(|v| -> Result<i32> { Self::day_timestamp_micro(v) })?,
277 DataType::Timestamp(TimeUnit::Nanosecond, _) => input
278 .as_any()
279 .downcast_ref::<TimestampNanosecondArray>()
280 .unwrap()
281 .try_unary(|v| -> Result<i32> { Self::day_timestamp_nano(v) })?,
282 DataType::Date32 => input
283 .as_any()
284 .downcast_ref::<Date32Array>()
285 .unwrap()
286 .unary(|v| -> i32 { v }),
287 _ => {
288 return Err(Error::new(
289 ErrorKind::Unexpected,
290 format!(
291 "Should not call internally for unsupported data type {:?}",
292 input.data_type()
293 ),
294 ));
295 }
296 };
297 Ok(Arc::new(res))
298 }
299
300 fn transform_literal(&self, input: &crate::spec::Datum) -> Result<Option<crate::spec::Datum>> {
301 let val = match (input.data_type(), input.literal()) {
302 (PrimitiveType::Date, PrimitiveLiteral::Int(v)) => *v,
303 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) => Self::day_timestamp_micro(*v)?,
304 (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) => {
305 Self::day_timestamp_micro(*v)?
306 }
307 (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
308 Self::day_timestamp_nano(*v)?
309 }
310 (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
311 Self::day_timestamp_nano(*v)?
312 }
313 _ => {
314 return Err(crate::Error::new(
315 crate::ErrorKind::FeatureUnsupported,
316 format!(
317 "Unsupported data type for day transform: {:?}",
318 input.data_type()
319 ),
320 ));
321 }
322 };
323 Ok(Some(Datum::date(val)))
324 }
325}
326
327#[derive(Debug)]
329pub struct Hour;
330
331impl Hour {
332 #[inline]
333 fn hour_timestamp_micro(v: i64) -> i32 {
334 v.div_euclid(MICROSECONDS_PER_HOUR) as i32
335 }
336
337 #[inline]
338 fn hour_timestamp_nano(v: i64) -> i32 {
339 v.div_euclid(NANOSECONDS_PER_HOUR) as i32
340 }
341}
342
343impl TransformFunction for Hour {
344 fn transform(&self, input: ArrayRef) -> Result<ArrayRef> {
345 let res: Int32Array = match input.data_type() {
346 DataType::Timestamp(TimeUnit::Microsecond, _) => input
347 .as_any()
348 .downcast_ref::<TimestampMicrosecondArray>()
349 .unwrap()
350 .unary(|v| -> i32 { Self::hour_timestamp_micro(v) }),
351 _ => {
352 return Err(crate::Error::new(
353 crate::ErrorKind::FeatureUnsupported,
354 format!(
355 "Unsupported data type for hour transform: {:?}",
356 input.data_type()
357 ),
358 ));
359 }
360 };
361 Ok(Arc::new(res))
362 }
363
364 fn transform_literal(&self, input: &crate::spec::Datum) -> Result<Option<crate::spec::Datum>> {
365 let val = match (input.data_type(), input.literal()) {
366 (PrimitiveType::Timestamp, PrimitiveLiteral::Long(v)) => Self::hour_timestamp_micro(*v),
367 (PrimitiveType::Timestamptz, PrimitiveLiteral::Long(v)) => {
368 Self::hour_timestamp_micro(*v)
369 }
370 (PrimitiveType::TimestampNs, PrimitiveLiteral::Long(v)) => {
371 Self::hour_timestamp_nano(*v)
372 }
373 (PrimitiveType::TimestamptzNs, PrimitiveLiteral::Long(v)) => {
374 Self::hour_timestamp_nano(*v)
375 }
376 _ => {
377 return Err(crate::Error::new(
378 crate::ErrorKind::FeatureUnsupported,
379 format!(
380 "Unsupported data type for hour transform: {:?}",
381 input.data_type()
382 ),
383 ));
384 }
385 };
386 Ok(Some(Datum::int(val)))
387 }
388}
389
390#[cfg(test)]
391mod test {
392 use std::sync::Arc;
393
394 use arrow_array::{ArrayRef, Date32Array, Int32Array, TimestampMicrosecondArray};
395 use chrono::{NaiveDate, NaiveDateTime};
396
397 use crate::Result;
398 use crate::expr::PredicateOperator;
399 use crate::spec::PrimitiveType::{
400 Binary, Date, Decimal, Fixed, Int, Long, String as StringType, Time, Timestamp,
401 TimestampNs, Timestamptz, TimestamptzNs, Uuid,
402 };
403 use crate::spec::Type::{Primitive, Struct};
404 use crate::spec::{Datum, NestedField, PrimitiveType, StructType, Transform, Type};
405 use crate::transform::test::{TestProjectionFixture, TestTransformFixture};
406 use crate::transform::{BoxedTransformFunction, TransformFunction};
407
408 #[test]
409 fn test_year_transform() {
410 let trans = Transform::Year;
411
412 let fixture = TestTransformFixture {
413 display: "year".to_string(),
414 json: r#""year""#.to_string(),
415 dedup_name: "time".to_string(),
416 preserves_order: true,
417 satisfies_order_of: vec![
418 (Transform::Year, true),
419 (Transform::Month, false),
420 (Transform::Day, false),
421 (Transform::Hour, false),
422 (Transform::Void, false),
423 (Transform::Identity, false),
424 ],
425 trans_types: vec![
426 (Primitive(Binary), None),
427 (Primitive(Date), Some(Primitive(Int))),
428 (
429 Primitive(Decimal {
430 precision: 8,
431 scale: 5,
432 }),
433 None,
434 ),
435 (Primitive(Fixed(8)), None),
436 (Primitive(Int), None),
437 (Primitive(Long), None),
438 (Primitive(StringType), None),
439 (Primitive(Uuid), None),
440 (Primitive(Time), None),
441 (Primitive(Timestamp), Some(Primitive(Int))),
442 (Primitive(Timestamptz), Some(Primitive(Int))),
443 (Primitive(TimestampNs), Some(Primitive(Int))),
444 (Primitive(TimestamptzNs), Some(Primitive(Int))),
445 (
446 Struct(StructType::new(vec![
447 NestedField::optional(1, "a", Primitive(Timestamp)).into(),
448 ])),
449 None,
450 ),
451 ],
452 };
453
454 fixture.assert_transform(trans);
455 }
456
457 #[test]
458 fn test_month_transform() {
459 let trans = Transform::Month;
460
461 let fixture = TestTransformFixture {
462 display: "month".to_string(),
463 json: r#""month""#.to_string(),
464 dedup_name: "time".to_string(),
465 preserves_order: true,
466 satisfies_order_of: vec![
467 (Transform::Year, true),
468 (Transform::Month, true),
469 (Transform::Day, false),
470 (Transform::Hour, false),
471 (Transform::Void, false),
472 (Transform::Identity, false),
473 ],
474 trans_types: vec![
475 (Primitive(Binary), None),
476 (Primitive(Date), Some(Primitive(Int))),
477 (
478 Primitive(Decimal {
479 precision: 8,
480 scale: 5,
481 }),
482 None,
483 ),
484 (Primitive(Fixed(8)), None),
485 (Primitive(Int), None),
486 (Primitive(Long), None),
487 (Primitive(StringType), None),
488 (Primitive(Uuid), None),
489 (Primitive(Time), None),
490 (Primitive(Timestamp), Some(Primitive(Int))),
491 (Primitive(Timestamptz), Some(Primitive(Int))),
492 (Primitive(TimestampNs), Some(Primitive(Int))),
493 (Primitive(TimestamptzNs), Some(Primitive(Int))),
494 (
495 Struct(StructType::new(vec![
496 NestedField::optional(1, "a", Primitive(Timestamp)).into(),
497 ])),
498 None,
499 ),
500 ],
501 };
502
503 fixture.assert_transform(trans);
504 }
505
506 #[test]
507 fn test_day_transform() {
508 let trans = Transform::Day;
509
510 let fixture = TestTransformFixture {
511 display: "day".to_string(),
512 json: r#""day""#.to_string(),
513 dedup_name: "time".to_string(),
514 preserves_order: true,
515 satisfies_order_of: vec![
516 (Transform::Year, true),
517 (Transform::Month, true),
518 (Transform::Day, true),
519 (Transform::Hour, false),
520 (Transform::Void, false),
521 (Transform::Identity, false),
522 ],
523 trans_types: vec![
524 (Primitive(Binary), None),
525 (Primitive(Date), Some(Primitive(Date))),
526 (
527 Primitive(Decimal {
528 precision: 8,
529 scale: 5,
530 }),
531 None,
532 ),
533 (Primitive(Fixed(8)), None),
534 (Primitive(Int), None),
535 (Primitive(Long), None),
536 (Primitive(StringType), None),
537 (Primitive(Uuid), None),
538 (Primitive(Time), None),
539 (Primitive(Timestamp), Some(Primitive(Date))),
540 (Primitive(Timestamptz), Some(Primitive(Date))),
541 (Primitive(TimestampNs), Some(Primitive(Date))),
542 (Primitive(TimestamptzNs), Some(Primitive(Date))),
543 (
544 Struct(StructType::new(vec![
545 NestedField::optional(1, "a", Primitive(Timestamp)).into(),
546 ])),
547 None,
548 ),
549 ],
550 };
551
552 fixture.assert_transform(trans);
553 }
554
555 #[test]
556 fn test_hour_transform() {
557 let trans = Transform::Hour;
558
559 let fixture = TestTransformFixture {
560 display: "hour".to_string(),
561 json: r#""hour""#.to_string(),
562 dedup_name: "time".to_string(),
563 preserves_order: true,
564 satisfies_order_of: vec![
565 (Transform::Year, true),
566 (Transform::Month, true),
567 (Transform::Day, true),
568 (Transform::Hour, true),
569 (Transform::Void, false),
570 (Transform::Identity, false),
571 ],
572 trans_types: vec![
573 (Primitive(Binary), None),
574 (Primitive(Date), None),
575 (
576 Primitive(Decimal {
577 precision: 8,
578 scale: 5,
579 }),
580 None,
581 ),
582 (Primitive(Fixed(8)), None),
583 (Primitive(Int), None),
584 (Primitive(Long), None),
585 (Primitive(StringType), None),
586 (Primitive(Uuid), None),
587 (Primitive(Time), None),
588 (Primitive(Timestamp), Some(Primitive(Int))),
589 (Primitive(Timestamptz), Some(Primitive(Int))),
590 (Primitive(TimestampNs), Some(Primitive(Int))),
591 (Primitive(TimestamptzNs), Some(Primitive(Int))),
592 (
593 Struct(StructType::new(vec![
594 NestedField::optional(1, "a", Primitive(Timestamp)).into(),
595 ])),
596 None,
597 ),
598 ],
599 };
600
601 fixture.assert_transform(trans);
602 }
603
604 #[test]
605 fn test_projection_timestamp_hour_upper_bound() -> Result<()> {
606 let value = "2017-12-01T10:59:59.999999";
608 let another = "2016-12-31T23:59:59.999999";
610
611 let fixture = TestProjectionFixture::new(
612 Transform::Hour,
613 "name",
614 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
615 );
616
617 fixture.assert_projection(
618 &fixture.binary_predicate(
619 PredicateOperator::LessThan,
620 Datum::timestamp_from_str(value)?,
621 ),
622 Some("name <= 420034"),
623 )?;
624
625 fixture.assert_projection(
626 &fixture.binary_predicate(
627 PredicateOperator::LessThanOrEq,
628 Datum::timestamp_from_str(value)?,
629 ),
630 Some("name <= 420034"),
631 )?;
632
633 fixture.assert_projection(
634 &fixture.binary_predicate(
635 PredicateOperator::GreaterThan,
636 Datum::timestamp_from_str(value)?,
637 ),
638 Some("name >= 420035"),
639 )?;
640
641 fixture.assert_projection(
642 &fixture.binary_predicate(
643 PredicateOperator::GreaterThanOrEq,
644 Datum::timestamp_from_str(value)?,
645 ),
646 Some("name >= 420034"),
647 )?;
648
649 fixture.assert_projection(
650 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
651 Some("name = 420034"),
652 )?;
653
654 fixture.assert_projection(
655 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
656 None,
657 )?;
658
659 fixture.assert_projection(
660 &fixture.set_predicate(PredicateOperator::In, vec![
661 Datum::timestamp_from_str(value)?,
662 Datum::timestamp_from_str(another)?,
663 ]),
664 Some("name IN (420034, 412007)"),
665 )?;
666
667 fixture.assert_projection(
668 &fixture.set_predicate(PredicateOperator::NotIn, vec![
669 Datum::timestamp_from_str(value)?,
670 Datum::timestamp_from_str(another)?,
671 ]),
672 None,
673 )?;
674
675 Ok(())
676 }
677
678 #[test]
679 fn test_projection_timestamp_hour_lower_bound() -> Result<()> {
680 let value = "2017-12-01T10:00:00.000000";
682 let another = "2016-12-02T00:00:00.000000";
684
685 let fixture = TestProjectionFixture::new(
686 Transform::Hour,
687 "name",
688 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
689 );
690
691 fixture.assert_projection(
692 &fixture.binary_predicate(
693 PredicateOperator::LessThan,
694 Datum::timestamp_from_str(value)?,
695 ),
696 Some("name <= 420033"),
697 )?;
698
699 fixture.assert_projection(
700 &fixture.binary_predicate(
701 PredicateOperator::LessThanOrEq,
702 Datum::timestamp_from_str(value)?,
703 ),
704 Some("name <= 420034"),
705 )?;
706
707 fixture.assert_projection(
708 &fixture.binary_predicate(
709 PredicateOperator::GreaterThan,
710 Datum::timestamp_from_str(value)?,
711 ),
712 Some("name >= 420034"),
713 )?;
714
715 fixture.assert_projection(
716 &fixture.binary_predicate(
717 PredicateOperator::GreaterThanOrEq,
718 Datum::timestamp_from_str(value)?,
719 ),
720 Some("name >= 420034"),
721 )?;
722
723 fixture.assert_projection(
724 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
725 Some("name = 420034"),
726 )?;
727
728 fixture.assert_projection(
729 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
730 None,
731 )?;
732
733 fixture.assert_projection(
734 &fixture.set_predicate(PredicateOperator::In, vec![
735 Datum::timestamp_from_str(value)?,
736 Datum::timestamp_from_str(another)?,
737 ]),
738 Some("name IN (411288, 420034)"),
739 )?;
740
741 fixture.assert_projection(
742 &fixture.set_predicate(PredicateOperator::NotIn, vec![
743 Datum::timestamp_from_str(value)?,
744 Datum::timestamp_from_str(another)?,
745 ]),
746 None,
747 )?;
748
749 Ok(())
750 }
751
752 #[test]
753 fn test_projection_timestamp_year_upper_bound() -> Result<()> {
754 let value = "2017-12-31T23:59:59.999999";
755 let another = "2016-12-31T23:59:59.999999";
756
757 let fixture = TestProjectionFixture::new(
758 Transform::Year,
759 "name",
760 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
761 );
762
763 fixture.assert_projection(
764 &fixture.binary_predicate(
765 PredicateOperator::LessThan,
766 Datum::timestamp_from_str(value)?,
767 ),
768 Some("name <= 47"),
769 )?;
770
771 fixture.assert_projection(
772 &fixture.binary_predicate(
773 PredicateOperator::LessThanOrEq,
774 Datum::timestamp_from_str(value)?,
775 ),
776 Some("name <= 47"),
777 )?;
778
779 fixture.assert_projection(
780 &fixture.binary_predicate(
781 PredicateOperator::GreaterThan,
782 Datum::timestamp_from_str(value)?,
783 ),
784 Some("name >= 48"),
785 )?;
786
787 fixture.assert_projection(
788 &fixture.binary_predicate(
789 PredicateOperator::GreaterThanOrEq,
790 Datum::timestamp_from_str(value)?,
791 ),
792 Some("name >= 47"),
793 )?;
794
795 fixture.assert_projection(
796 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
797 Some("name = 47"),
798 )?;
799
800 fixture.assert_projection(
801 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
802 None,
803 )?;
804
805 fixture.assert_projection(
806 &fixture.set_predicate(PredicateOperator::In, vec![
807 Datum::timestamp_from_str(value)?,
808 Datum::timestamp_from_str(another)?,
809 ]),
810 Some("name IN (47, 46)"),
811 )?;
812
813 fixture.assert_projection(
814 &fixture.set_predicate(PredicateOperator::NotIn, vec![
815 Datum::timestamp_from_str(value)?,
816 Datum::timestamp_from_str(another)?,
817 ]),
818 None,
819 )?;
820
821 Ok(())
822 }
823
824 #[test]
825 fn test_projection_timestamp_year_lower_bound() -> Result<()> {
826 let value = "2017-01-01T00:00:00.000000";
827 let another = "2016-12-02T00:00:00.000000";
828
829 let fixture = TestProjectionFixture::new(
830 Transform::Year,
831 "name",
832 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
833 );
834
835 fixture.assert_projection(
836 &fixture.binary_predicate(
837 PredicateOperator::LessThan,
838 Datum::timestamp_from_str(value)?,
839 ),
840 Some("name <= 46"),
841 )?;
842
843 fixture.assert_projection(
844 &fixture.binary_predicate(
845 PredicateOperator::LessThanOrEq,
846 Datum::timestamp_from_str(value)?,
847 ),
848 Some("name <= 47"),
849 )?;
850
851 fixture.assert_projection(
852 &fixture.binary_predicate(
853 PredicateOperator::GreaterThan,
854 Datum::timestamp_from_str(value)?,
855 ),
856 Some("name >= 47"),
857 )?;
858
859 fixture.assert_projection(
860 &fixture.binary_predicate(
861 PredicateOperator::GreaterThanOrEq,
862 Datum::timestamp_from_str(value)?,
863 ),
864 Some("name >= 47"),
865 )?;
866
867 fixture.assert_projection(
868 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
869 Some("name = 47"),
870 )?;
871
872 fixture.assert_projection(
873 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
874 None,
875 )?;
876
877 fixture.assert_projection(
878 &fixture.set_predicate(PredicateOperator::In, vec![
879 Datum::timestamp_from_str(value)?,
880 Datum::timestamp_from_str(another)?,
881 ]),
882 Some("name IN (47, 46)"),
883 )?;
884
885 fixture.assert_projection(
886 &fixture.set_predicate(PredicateOperator::NotIn, vec![
887 Datum::timestamp_from_str(value)?,
888 Datum::timestamp_from_str(another)?,
889 ]),
890 None,
891 )?;
892
893 Ok(())
894 }
895
896 #[test]
897 fn test_projection_timestamp_month_negative_upper_bound() -> Result<()> {
898 let value = "1969-12-31T23:59:59.999999";
899 let another = "1970-01-01T00:00:00.000000";
900
901 let fixture = TestProjectionFixture::new(
902 Transform::Month,
903 "name",
904 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
905 );
906
907 fixture.assert_projection(
908 &fixture.binary_predicate(
909 PredicateOperator::LessThan,
910 Datum::timestamp_from_str(value)?,
911 ),
912 Some("name <= 0"),
913 )?;
914
915 fixture.assert_projection(
916 &fixture.binary_predicate(
917 PredicateOperator::LessThanOrEq,
918 Datum::timestamp_from_str(value)?,
919 ),
920 Some("name <= 0"),
921 )?;
922
923 fixture.assert_projection(
924 &fixture.binary_predicate(
925 PredicateOperator::GreaterThan,
926 Datum::timestamp_from_str(value)?,
927 ),
928 Some("name >= 0"),
929 )?;
930
931 fixture.assert_projection(
932 &fixture.binary_predicate(
933 PredicateOperator::GreaterThanOrEq,
934 Datum::timestamp_from_str(value)?,
935 ),
936 Some("name >= -1"),
937 )?;
938
939 fixture.assert_projection(
940 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
941 Some("name IN (-1, 0)"),
942 )?;
943
944 fixture.assert_projection(
945 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
946 None,
947 )?;
948
949 fixture.assert_projection(
950 &fixture.set_predicate(PredicateOperator::In, vec![
951 Datum::timestamp_from_str(value)?,
952 Datum::timestamp_from_str(another)?,
953 ]),
954 Some("name IN (0, -1)"),
955 )?;
956
957 fixture.assert_projection(
958 &fixture.set_predicate(PredicateOperator::NotIn, vec![
959 Datum::timestamp_from_str(value)?,
960 Datum::timestamp_from_str(another)?,
961 ]),
962 None,
963 )?;
964
965 Ok(())
966 }
967
968 #[test]
969 fn test_projection_timestamp_month_upper_bound() -> Result<()> {
970 let value = "2017-12-01T23:59:59.999999";
971 let another = "2017-11-02T00:00:00.000000";
972
973 let fixture = TestProjectionFixture::new(
974 Transform::Month,
975 "name",
976 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
977 );
978
979 fixture.assert_projection(
980 &fixture.binary_predicate(
981 PredicateOperator::LessThan,
982 Datum::timestamp_from_str(value)?,
983 ),
984 Some("name <= 575"),
985 )?;
986
987 fixture.assert_projection(
988 &fixture.binary_predicate(
989 PredicateOperator::LessThanOrEq,
990 Datum::timestamp_from_str(value)?,
991 ),
992 Some("name <= 575"),
993 )?;
994
995 fixture.assert_projection(
996 &fixture.binary_predicate(
997 PredicateOperator::GreaterThan,
998 Datum::timestamp_from_str(value)?,
999 ),
1000 Some("name >= 575"),
1001 )?;
1002
1003 fixture.assert_projection(
1004 &fixture.binary_predicate(
1005 PredicateOperator::GreaterThanOrEq,
1006 Datum::timestamp_from_str(value)?,
1007 ),
1008 Some("name >= 575"),
1009 )?;
1010
1011 fixture.assert_projection(
1012 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1013 Some("name = 575"),
1014 )?;
1015
1016 fixture.assert_projection(
1017 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1018 None,
1019 )?;
1020
1021 fixture.assert_projection(
1022 &fixture.set_predicate(PredicateOperator::In, vec![
1023 Datum::timestamp_from_str(value)?,
1024 Datum::timestamp_from_str(another)?,
1025 ]),
1026 Some("name IN (575, 574)"),
1027 )?;
1028
1029 fixture.assert_projection(
1030 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1031 Datum::timestamp_from_str(value)?,
1032 Datum::timestamp_from_str(another)?,
1033 ]),
1034 None,
1035 )?;
1036 Ok(())
1037 }
1038
1039 #[test]
1040 fn test_projection_timestamp_month_negative_lower_bound() -> Result<()> {
1041 let value = "1969-01-01T00:00:00.000000";
1042 let another = "1969-03-01T00:00:00.000000";
1043
1044 let fixture = TestProjectionFixture::new(
1045 Transform::Month,
1046 "name",
1047 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1048 );
1049
1050 fixture.assert_projection(
1051 &fixture.binary_predicate(
1052 PredicateOperator::LessThan,
1053 Datum::timestamp_from_str(value)?,
1054 ),
1055 Some("name <= -12"),
1056 )?;
1057
1058 fixture.assert_projection(
1059 &fixture.binary_predicate(
1060 PredicateOperator::LessThanOrEq,
1061 Datum::timestamp_from_str(value)?,
1062 ),
1063 Some("name <= -11"),
1064 )?;
1065
1066 fixture.assert_projection(
1067 &fixture.binary_predicate(
1068 PredicateOperator::GreaterThan,
1069 Datum::timestamp_from_str(value)?,
1070 ),
1071 Some("name >= -12"),
1072 )?;
1073
1074 fixture.assert_projection(
1075 &fixture.binary_predicate(
1076 PredicateOperator::GreaterThanOrEq,
1077 Datum::timestamp_from_str(value)?,
1078 ),
1079 Some("name >= -12"),
1080 )?;
1081
1082 fixture.assert_projection(
1083 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1084 Some("name IN (-12, -11)"),
1085 )?;
1086
1087 fixture.assert_projection(
1088 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1089 None,
1090 )?;
1091
1092 fixture.assert_projection(
1093 &fixture.set_predicate(PredicateOperator::In, vec![
1094 Datum::timestamp_from_str(value)?,
1095 Datum::timestamp_from_str(another)?,
1096 ]),
1097 Some("name IN (-10, -9, -12, -11)"),
1098 )?;
1099
1100 fixture.assert_projection(
1101 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1102 Datum::timestamp_from_str(value)?,
1103 Datum::timestamp_from_str(another)?,
1104 ]),
1105 None,
1106 )?;
1107
1108 Ok(())
1109 }
1110
1111 #[test]
1112 fn test_projection_timestamp_month_lower_bound() -> Result<()> {
1113 let value = "2017-12-01T00:00:00.000000";
1114 let another = "2017-12-02T00:00:00.000000";
1115
1116 let fixture = TestProjectionFixture::new(
1117 Transform::Month,
1118 "name",
1119 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1120 );
1121
1122 fixture.assert_projection(
1123 &fixture.binary_predicate(
1124 PredicateOperator::LessThan,
1125 Datum::timestamp_from_str(value)?,
1126 ),
1127 Some("name <= 574"),
1128 )?;
1129
1130 fixture.assert_projection(
1131 &fixture.binary_predicate(
1132 PredicateOperator::LessThanOrEq,
1133 Datum::timestamp_from_str(value)?,
1134 ),
1135 Some("name <= 575"),
1136 )?;
1137
1138 fixture.assert_projection(
1139 &fixture.binary_predicate(
1140 PredicateOperator::GreaterThan,
1141 Datum::timestamp_from_str(value)?,
1142 ),
1143 Some("name >= 575"),
1144 )?;
1145
1146 fixture.assert_projection(
1147 &fixture.binary_predicate(
1148 PredicateOperator::GreaterThanOrEq,
1149 Datum::timestamp_from_str(value)?,
1150 ),
1151 Some("name >= 575"),
1152 )?;
1153
1154 fixture.assert_projection(
1155 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1156 Some("name = 575"),
1157 )?;
1158
1159 fixture.assert_projection(
1160 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1161 None,
1162 )?;
1163
1164 fixture.assert_projection(
1165 &fixture.set_predicate(PredicateOperator::In, vec![
1166 Datum::timestamp_from_str(value)?,
1167 Datum::timestamp_from_str(another)?,
1168 ]),
1169 Some("name IN (575)"),
1170 )?;
1171
1172 fixture.assert_projection(
1173 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1174 Datum::timestamp_from_str(value)?,
1175 Datum::timestamp_from_str(another)?,
1176 ]),
1177 None,
1178 )?;
1179
1180 Ok(())
1181 }
1182
1183 #[test]
1184 fn test_projection_timestamp_day_negative_upper_bound() -> Result<()> {
1185 let value = "1969-12-31T23:59:59.999999";
1187 let another = "1970-01-01T00:00:00.000000";
1189
1190 let fixture = TestProjectionFixture::new(
1191 Transform::Day,
1192 "name",
1193 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1194 );
1195
1196 fixture.assert_projection(
1197 &fixture.binary_predicate(
1198 PredicateOperator::LessThan,
1199 Datum::timestamp_from_str(value)?,
1200 ),
1201 Some("name <= 1970-01-01"),
1202 )?;
1203
1204 fixture.assert_projection(
1205 &fixture.binary_predicate(
1206 PredicateOperator::LessThanOrEq,
1207 Datum::timestamp_from_str(value)?,
1208 ),
1209 Some("name <= 1970-01-01"),
1210 )?;
1211
1212 fixture.assert_projection(
1213 &fixture.binary_predicate(
1214 PredicateOperator::GreaterThan,
1215 Datum::timestamp_from_str(value)?,
1216 ),
1217 Some("name >= 1970-01-01"),
1218 )?;
1219
1220 fixture.assert_projection(
1221 &fixture.binary_predicate(
1222 PredicateOperator::GreaterThanOrEq,
1223 Datum::timestamp_from_str(value)?,
1224 ),
1225 Some("name >= 1969-12-31"),
1226 )?;
1227
1228 fixture.assert_projection(
1229 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1230 Some("name IN (1969-12-31, 1970-01-01)"),
1231 )?;
1232
1233 fixture.assert_projection(
1234 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1235 None,
1236 )?;
1237
1238 fixture.assert_projection(
1239 &fixture.set_predicate(PredicateOperator::In, vec![
1240 Datum::timestamp_from_str(value)?,
1241 Datum::timestamp_from_str(another)?,
1242 ]),
1243 Some("name IN (1970-01-01, 1969-12-31)"),
1244 )?;
1245
1246 fixture.assert_projection(
1247 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1248 Datum::timestamp_from_str(value)?,
1249 Datum::timestamp_from_str(another)?,
1250 ]),
1251 None,
1252 )?;
1253
1254 Ok(())
1255 }
1256
1257 #[test]
1258 fn test_projection_timestamp_day_upper_bound() -> Result<()> {
1259 let value = "2017-12-01T23:59:59.999999";
1261 let another = "2017-12-02T00:00:00.000000";
1263
1264 let fixture = TestProjectionFixture::new(
1265 Transform::Day,
1266 "name",
1267 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1268 );
1269
1270 fixture.assert_projection(
1271 &fixture.binary_predicate(
1272 PredicateOperator::LessThan,
1273 Datum::timestamp_from_str(value)?,
1274 ),
1275 Some("name <= 2017-12-01"),
1276 )?;
1277
1278 fixture.assert_projection(
1279 &fixture.binary_predicate(
1280 PredicateOperator::LessThanOrEq,
1281 Datum::timestamp_from_str(value)?,
1282 ),
1283 Some("name <= 2017-12-01"),
1284 )?;
1285
1286 fixture.assert_projection(
1287 &fixture.binary_predicate(
1288 PredicateOperator::GreaterThan,
1289 Datum::timestamp_from_str(value)?,
1290 ),
1291 Some("name >= 2017-12-02"),
1292 )?;
1293
1294 fixture.assert_projection(
1295 &fixture.binary_predicate(
1296 PredicateOperator::GreaterThanOrEq,
1297 Datum::timestamp_from_str(value)?,
1298 ),
1299 Some("name >= 2017-12-01"),
1300 )?;
1301
1302 fixture.assert_projection(
1303 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1304 Some("name = 2017-12-01"),
1305 )?;
1306
1307 fixture.assert_projection(
1308 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1309 None,
1310 )?;
1311
1312 fixture.assert_projection(
1313 &fixture.set_predicate(PredicateOperator::In, vec![
1314 Datum::timestamp_from_str(value)?,
1315 Datum::timestamp_from_str(another)?,
1316 ]),
1317 Some("name IN (2017-12-02, 2017-12-01)"),
1318 )?;
1319
1320 fixture.assert_projection(
1321 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1322 Datum::timestamp_from_str(value)?,
1323 Datum::timestamp_from_str(another)?,
1324 ]),
1325 None,
1326 )?;
1327
1328 Ok(())
1329 }
1330
1331 #[test]
1332 fn test_projection_timestamp_day_negative_lower_bound() -> Result<()> {
1333 let value = "1969-01-01T00:00:00.000000";
1335 let another = "1969-01-02T00:00:00.000000";
1337
1338 let fixture = TestProjectionFixture::new(
1339 Transform::Day,
1340 "name",
1341 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1342 );
1343
1344 fixture.assert_projection(
1345 &fixture.binary_predicate(
1346 PredicateOperator::LessThan,
1347 Datum::timestamp_from_str(value)?,
1348 ),
1349 Some("name <= 1969-01-01"),
1350 )?;
1351
1352 fixture.assert_projection(
1353 &fixture.binary_predicate(
1354 PredicateOperator::LessThanOrEq,
1355 Datum::timestamp_from_str(value)?,
1356 ),
1357 Some("name <= 1969-01-02"),
1358 )?;
1359
1360 fixture.assert_projection(
1361 &fixture.binary_predicate(
1362 PredicateOperator::GreaterThan,
1363 Datum::timestamp_from_str(value)?,
1364 ),
1365 Some("name >= 1969-01-01"),
1366 )?;
1367
1368 fixture.assert_projection(
1369 &fixture.binary_predicate(
1370 PredicateOperator::GreaterThanOrEq,
1371 Datum::timestamp_from_str(value)?,
1372 ),
1373 Some("name >= 1969-01-01"),
1374 )?;
1375
1376 fixture.assert_projection(
1377 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1378 Some("name IN (1969-01-01, 1969-01-02)"),
1379 )?;
1380
1381 fixture.assert_projection(
1382 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1383 None,
1384 )?;
1385
1386 fixture.assert_projection(
1387 &fixture.set_predicate(PredicateOperator::In, vec![
1388 Datum::timestamp_from_str(value)?,
1389 Datum::timestamp_from_str(another)?,
1390 ]),
1391 Some("name IN (1969-01-02, 1969-01-01, 1969-01-03)"),
1392 )?;
1393
1394 fixture.assert_projection(
1395 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1396 Datum::timestamp_from_str(value)?,
1397 Datum::timestamp_from_str(another)?,
1398 ]),
1399 None,
1400 )?;
1401
1402 Ok(())
1403 }
1404
1405 #[test]
1406 fn test_projection_timestamp_day_lower_bound() -> Result<()> {
1407 let value = "2017-12-01T00:00:00.000000";
1409 let another = "2017-12-02T00:00:00.000000";
1411
1412 let fixture = TestProjectionFixture::new(
1413 Transform::Day,
1414 "name",
1415 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1416 );
1417
1418 fixture.assert_projection(
1419 &fixture.binary_predicate(
1420 PredicateOperator::LessThan,
1421 Datum::timestamp_from_str(value)?,
1422 ),
1423 Some("name <= 2017-11-30"),
1424 )?;
1425
1426 fixture.assert_projection(
1427 &fixture.binary_predicate(
1428 PredicateOperator::LessThanOrEq,
1429 Datum::timestamp_from_str(value)?,
1430 ),
1431 Some("name <= 2017-12-01"),
1432 )?;
1433
1434 fixture.assert_projection(
1435 &fixture.binary_predicate(
1436 PredicateOperator::GreaterThan,
1437 Datum::timestamp_from_str(value)?,
1438 ),
1439 Some("name >= 2017-12-01"),
1440 )?;
1441
1442 fixture.assert_projection(
1443 &fixture.binary_predicate(
1444 PredicateOperator::GreaterThanOrEq,
1445 Datum::timestamp_from_str(value)?,
1446 ),
1447 Some("name >= 2017-12-01"),
1448 )?;
1449
1450 fixture.assert_projection(
1451 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1452 Some("name = 2017-12-01"),
1453 )?;
1454
1455 fixture.assert_projection(
1456 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1457 None,
1458 )?;
1459
1460 fixture.assert_projection(
1461 &fixture.set_predicate(PredicateOperator::In, vec![
1462 Datum::timestamp_from_str(value)?,
1463 Datum::timestamp_from_str(another)?,
1464 ]),
1465 Some("name IN (2017-12-02, 2017-12-01)"),
1466 )?;
1467
1468 fixture.assert_projection(
1469 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1470 Datum::timestamp_from_str(value)?,
1471 Datum::timestamp_from_str(another)?,
1472 ]),
1473 None,
1474 )?;
1475
1476 Ok(())
1477 }
1478
1479 #[test]
1480 fn test_projection_timestamp_day_epoch() -> Result<()> {
1481 let value = "1970-01-01T00:00:00.00000";
1483 let another = "1970-01-02T00:00:00.00000";
1485
1486 let fixture = TestProjectionFixture::new(
1487 Transform::Day,
1488 "name",
1489 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Timestamp)),
1490 );
1491
1492 fixture.assert_projection(
1493 &fixture.binary_predicate(
1494 PredicateOperator::LessThan,
1495 Datum::timestamp_from_str(value)?,
1496 ),
1497 Some("name <= 1970-01-01"),
1498 )?;
1499
1500 fixture.assert_projection(
1501 &fixture.binary_predicate(
1502 PredicateOperator::LessThanOrEq,
1503 Datum::timestamp_from_str(value)?,
1504 ),
1505 Some("name <= 1970-01-01"),
1506 )?;
1507
1508 fixture.assert_projection(
1509 &fixture.binary_predicate(
1510 PredicateOperator::GreaterThan,
1511 Datum::timestamp_from_str(value)?,
1512 ),
1513 Some("name >= 1970-01-01"),
1514 )?;
1515
1516 fixture.assert_projection(
1517 &fixture.binary_predicate(
1518 PredicateOperator::GreaterThanOrEq,
1519 Datum::timestamp_from_str(value)?,
1520 ),
1521 Some("name >= 1970-01-01"),
1522 )?;
1523
1524 fixture.assert_projection(
1525 &fixture.binary_predicate(PredicateOperator::Eq, Datum::timestamp_from_str(value)?),
1526 Some("name = 1970-01-01"),
1527 )?;
1528
1529 fixture.assert_projection(
1530 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::timestamp_from_str(value)?),
1531 None,
1532 )?;
1533
1534 fixture.assert_projection(
1535 &fixture.set_predicate(PredicateOperator::In, vec![
1536 Datum::timestamp_from_str(value)?,
1537 Datum::timestamp_from_str(another)?,
1538 ]),
1539 Some("name IN (1970-01-01, 1970-01-02)"),
1540 )?;
1541
1542 fixture.assert_projection(
1543 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1544 Datum::timestamp_from_str(value)?,
1545 Datum::timestamp_from_str(another)?,
1546 ]),
1547 None,
1548 )?;
1549
1550 Ok(())
1551 }
1552
1553 #[test]
1554 fn test_projection_date_day_negative() -> Result<()> {
1555 let value = "1969-12-30";
1557 let another = "1969-12-28";
1559
1560 let fixture = TestProjectionFixture::new(
1561 Transform::Day,
1562 "name",
1563 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1564 );
1565
1566 fixture.assert_projection(
1567 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1568 Some("name <= 1969-12-29"),
1569 )?;
1570
1571 fixture.assert_projection(
1572 &fixture.binary_predicate(
1573 PredicateOperator::LessThanOrEq,
1574 Datum::date_from_str(value)?,
1575 ),
1576 Some("name <= 1969-12-30"),
1577 )?;
1578
1579 fixture.assert_projection(
1580 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1581 Some("name >= 1969-12-31"),
1582 )?;
1583
1584 fixture.assert_projection(
1585 &fixture.binary_predicate(
1586 PredicateOperator::GreaterThanOrEq,
1587 Datum::date_from_str(value)?,
1588 ),
1589 Some("name >= 1969-12-30"),
1590 )?;
1591
1592 fixture.assert_projection(
1593 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
1594 Some("name = 1969-12-30"),
1595 )?;
1596
1597 fixture.assert_projection(
1598 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
1599 None,
1600 )?;
1601
1602 fixture.assert_projection(
1603 &fixture.set_predicate(PredicateOperator::In, vec![
1604 Datum::date_from_str(value)?,
1605 Datum::date_from_str(another)?,
1606 ]),
1607 Some("name IN (1969-12-28, 1969-12-30)"),
1608 )?;
1609
1610 fixture.assert_projection(
1611 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1612 Datum::date_from_str(value)?,
1613 Datum::date_from_str(another)?,
1614 ]),
1615 None,
1616 )?;
1617
1618 Ok(())
1619 }
1620
1621 #[test]
1622 fn test_projection_date_day() -> Result<()> {
1623 let value = "2017-01-01";
1625 let another = "2017-12-31";
1627
1628 let fixture = TestProjectionFixture::new(
1629 Transform::Day,
1630 "name",
1631 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1632 );
1633
1634 fixture.assert_projection(
1635 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1636 Some("name <= 2016-12-31"),
1637 )?;
1638
1639 fixture.assert_projection(
1640 &fixture.binary_predicate(
1641 PredicateOperator::LessThanOrEq,
1642 Datum::date_from_str(value)?,
1643 ),
1644 Some("name <= 2017-01-01"),
1645 )?;
1646
1647 fixture.assert_projection(
1648 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1649 Some("name >= 2017-01-02"),
1650 )?;
1651
1652 fixture.assert_projection(
1653 &fixture.binary_predicate(
1654 PredicateOperator::GreaterThanOrEq,
1655 Datum::date_from_str(value)?,
1656 ),
1657 Some("name >= 2017-01-01"),
1658 )?;
1659
1660 fixture.assert_projection(
1661 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
1662 Some("name = 2017-01-01"),
1663 )?;
1664
1665 fixture.assert_projection(
1666 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
1667 None,
1668 )?;
1669
1670 fixture.assert_projection(
1671 &fixture.set_predicate(PredicateOperator::In, vec![
1672 Datum::date_from_str(value)?,
1673 Datum::date_from_str(another)?,
1674 ]),
1675 Some("name IN (2017-01-01, 2017-12-31)"),
1676 )?;
1677
1678 fixture.assert_projection(
1679 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1680 Datum::date_from_str(value)?,
1681 Datum::date_from_str(another)?,
1682 ]),
1683 None,
1684 )?;
1685
1686 Ok(())
1687 }
1688
1689 #[test]
1690 fn test_projection_date_month_negative_upper_bound() -> Result<()> {
1691 let value = "1969-12-31";
1693 let another = "1969-01-01";
1695
1696 let fixture = TestProjectionFixture::new(
1697 Transform::Month,
1698 "name",
1699 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1700 );
1701
1702 fixture.assert_projection(
1703 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1704 Some("name <= 0"),
1705 )?;
1706
1707 fixture.assert_projection(
1708 &fixture.binary_predicate(
1709 PredicateOperator::LessThanOrEq,
1710 Datum::date_from_str(value)?,
1711 ),
1712 Some("name <= 0"),
1713 )?;
1714
1715 fixture.assert_projection(
1716 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1717 Some("name >= 0"),
1718 )?;
1719
1720 fixture.assert_projection(
1721 &fixture.binary_predicate(
1722 PredicateOperator::GreaterThanOrEq,
1723 Datum::date_from_str(value)?,
1724 ),
1725 Some("name >= -1"),
1726 )?;
1727
1728 fixture.assert_projection(
1729 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
1730 Some("name IN (-1, 0)"),
1731 )?;
1732
1733 fixture.assert_projection(
1734 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
1735 None,
1736 )?;
1737
1738 fixture.assert_projection(
1739 &fixture.set_predicate(PredicateOperator::In, vec![
1740 Datum::date_from_str(value)?,
1741 Datum::date_from_str(another)?,
1742 ]),
1743 Some("name IN (-1, -12, -11, 0)"),
1744 )?;
1745
1746 fixture.assert_projection(
1747 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1748 Datum::date_from_str(value)?,
1749 Datum::date_from_str(another)?,
1750 ]),
1751 None,
1752 )?;
1753
1754 Ok(())
1755 }
1756
1757 #[test]
1758 fn test_projection_date_month_upper_bound() -> Result<()> {
1759 let value = "2017-12-31";
1761 let another = "2017-01-01";
1763
1764 let fixture = TestProjectionFixture::new(
1765 Transform::Month,
1766 "name",
1767 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1768 );
1769
1770 fixture.assert_projection(
1771 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1772 Some("name <= 575"),
1773 )?;
1774
1775 fixture.assert_projection(
1776 &fixture.binary_predicate(
1777 PredicateOperator::LessThanOrEq,
1778 Datum::date_from_str(value)?,
1779 ),
1780 Some("name <= 575"),
1781 )?;
1782
1783 fixture.assert_projection(
1784 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1785 Some("name >= 576"),
1786 )?;
1787
1788 fixture.assert_projection(
1789 &fixture.binary_predicate(
1790 PredicateOperator::GreaterThanOrEq,
1791 Datum::date_from_str(value)?,
1792 ),
1793 Some("name >= 575"),
1794 )?;
1795
1796 fixture.assert_projection(
1797 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
1798 Some("name = 575"),
1799 )?;
1800
1801 fixture.assert_projection(
1802 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
1803 None,
1804 )?;
1805
1806 fixture.assert_projection(
1807 &fixture.set_predicate(PredicateOperator::In, vec![
1808 Datum::date_from_str(value)?,
1809 Datum::date_from_str(another)?,
1810 ]),
1811 Some("name IN (575, 564)"),
1812 )?;
1813
1814 fixture.assert_projection(
1815 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1816 Datum::date_from_str(value)?,
1817 Datum::date_from_str(another)?,
1818 ]),
1819 None,
1820 )?;
1821
1822 Ok(())
1823 }
1824
1825 #[test]
1826 fn test_projection_date_month_negative_lower_bound() -> Result<()> {
1827 let value = "1969-01-01";
1829 let another = "1969-12-31";
1831
1832 let fixture = TestProjectionFixture::new(
1833 Transform::Month,
1834 "name",
1835 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1836 );
1837
1838 fixture.assert_projection(
1839 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1840 Some("name <= -12"),
1841 )?;
1842
1843 fixture.assert_projection(
1844 &fixture.binary_predicate(
1845 PredicateOperator::LessThanOrEq,
1846 Datum::date_from_str(value)?,
1847 ),
1848 Some("name <= -11"),
1849 )?;
1850
1851 fixture.assert_projection(
1852 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1853 Some("name >= -12"),
1854 )?;
1855
1856 fixture.assert_projection(
1857 &fixture.binary_predicate(
1858 PredicateOperator::GreaterThanOrEq,
1859 Datum::date_from_str(value)?,
1860 ),
1861 Some("name >= -12"),
1862 )?;
1863
1864 fixture.assert_projection(
1865 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
1866 Some("name IN (-12, -11)"),
1867 )?;
1868
1869 fixture.assert_projection(
1870 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
1871 None,
1872 )?;
1873
1874 fixture.assert_projection(
1875 &fixture.set_predicate(PredicateOperator::In, vec![
1876 Datum::date_from_str(value)?,
1877 Datum::date_from_str(another)?,
1878 ]),
1879 Some("name IN (-1, -12, -11, 0)"),
1880 )?;
1881
1882 fixture.assert_projection(
1883 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1884 Datum::date_from_str(value)?,
1885 Datum::date_from_str(another)?,
1886 ]),
1887 None,
1888 )?;
1889
1890 Ok(())
1891 }
1892
1893 #[test]
1894 fn test_projection_date_month_lower_bound() -> Result<()> {
1895 let value = "2017-12-01";
1897 let another = "2017-01-01";
1899
1900 let fixture = TestProjectionFixture::new(
1901 Transform::Month,
1902 "name",
1903 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1904 );
1905
1906 fixture.assert_projection(
1907 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1908 Some("name <= 574"),
1909 )?;
1910
1911 fixture.assert_projection(
1912 &fixture.binary_predicate(
1913 PredicateOperator::LessThanOrEq,
1914 Datum::date_from_str(value)?,
1915 ),
1916 Some("name <= 575"),
1917 )?;
1918
1919 fixture.assert_projection(
1920 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1921 Some("name >= 575"),
1922 )?;
1923
1924 fixture.assert_projection(
1925 &fixture.binary_predicate(
1926 PredicateOperator::GreaterThanOrEq,
1927 Datum::date_from_str(value)?,
1928 ),
1929 Some("name >= 575"),
1930 )?;
1931
1932 fixture.assert_projection(
1933 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
1934 Some("name = 575"),
1935 )?;
1936
1937 fixture.assert_projection(
1938 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
1939 None,
1940 )?;
1941
1942 fixture.assert_projection(
1943 &fixture.set_predicate(PredicateOperator::In, vec![
1944 Datum::date_from_str(value)?,
1945 Datum::date_from_str(another)?,
1946 ]),
1947 Some("name IN (575, 564)"),
1948 )?;
1949
1950 fixture.assert_projection(
1951 &fixture.set_predicate(PredicateOperator::NotIn, vec![
1952 Datum::date_from_str(value)?,
1953 Datum::date_from_str(another)?,
1954 ]),
1955 None,
1956 )?;
1957
1958 Ok(())
1959 }
1960
1961 #[test]
1962 fn test_projection_date_month_epoch() -> Result<()> {
1963 let value = "1970-01-01";
1965 let another = "1969-12-31";
1967
1968 let fixture = TestProjectionFixture::new(
1969 Transform::Month,
1970 "name",
1971 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
1972 );
1973
1974 fixture.assert_projection(
1975 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
1976 Some("name <= 0"),
1977 )?;
1978
1979 fixture.assert_projection(
1980 &fixture.binary_predicate(
1981 PredicateOperator::LessThanOrEq,
1982 Datum::date_from_str(value)?,
1983 ),
1984 Some("name <= 0"),
1985 )?;
1986
1987 fixture.assert_projection(
1988 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
1989 Some("name >= 0"),
1990 )?;
1991
1992 fixture.assert_projection(
1993 &fixture.binary_predicate(
1994 PredicateOperator::GreaterThanOrEq,
1995 Datum::date_from_str(value)?,
1996 ),
1997 Some("name >= 0"),
1998 )?;
1999
2000 fixture.assert_projection(
2001 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
2002 Some("name = 0"),
2003 )?;
2004
2005 fixture.assert_projection(
2006 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
2007 None,
2008 )?;
2009
2010 fixture.assert_projection(
2011 &fixture.set_predicate(PredicateOperator::In, vec![
2012 Datum::date_from_str(value)?,
2013 Datum::date_from_str(another)?,
2014 ]),
2015 Some("name IN (0, -1)"),
2016 )?;
2017
2018 fixture.assert_projection(
2019 &fixture.set_predicate(PredicateOperator::NotIn, vec![
2020 Datum::date_from_str(value)?,
2021 Datum::date_from_str(another)?,
2022 ]),
2023 None,
2024 )?;
2025
2026 Ok(())
2027 }
2028
2029 #[test]
2030 fn test_projection_date_year_negative_upper_bound() -> Result<()> {
2031 let value = "1969-12-31";
2033 let another = "1969-01-01";
2034
2035 let fixture = TestProjectionFixture::new(
2036 Transform::Year,
2037 "name",
2038 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
2039 );
2040
2041 fixture.assert_projection(
2042 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
2043 Some("name <= 0"),
2044 )?;
2045
2046 fixture.assert_projection(
2047 &fixture.binary_predicate(
2048 PredicateOperator::LessThanOrEq,
2049 Datum::date_from_str(value)?,
2050 ),
2051 Some("name <= 0"),
2052 )?;
2053
2054 fixture.assert_projection(
2055 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
2056 Some("name >= 0"),
2057 )?;
2058
2059 fixture.assert_projection(
2060 &fixture.binary_predicate(
2061 PredicateOperator::GreaterThanOrEq,
2062 Datum::date_from_str(value)?,
2063 ),
2064 Some("name >= -1"),
2065 )?;
2066
2067 fixture.assert_projection(
2068 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
2069 Some("name IN (-1, 0)"),
2070 )?;
2071
2072 fixture.assert_projection(
2073 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
2074 None,
2075 )?;
2076
2077 fixture.assert_projection(
2078 &fixture.set_predicate(PredicateOperator::In, vec![
2079 Datum::date_from_str(value)?,
2080 Datum::date_from_str(another)?,
2081 ]),
2082 Some("name IN (0, -1)"),
2083 )?;
2084
2085 fixture.assert_projection(
2086 &fixture.set_predicate(PredicateOperator::NotIn, vec![
2087 Datum::date_from_str(value)?,
2088 Datum::date_from_str(another)?,
2089 ]),
2090 None,
2091 )?;
2092
2093 Ok(())
2094 }
2095
2096 #[test]
2097 fn test_projection_date_year_upper_bound() -> Result<()> {
2098 let value = "2017-12-31";
2100 let another = "2016-01-01";
2102
2103 let fixture = TestProjectionFixture::new(
2104 Transform::Year,
2105 "name",
2106 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
2107 );
2108
2109 fixture.assert_projection(
2110 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
2111 Some("name <= 47"),
2112 )?;
2113
2114 fixture.assert_projection(
2115 &fixture.binary_predicate(
2116 PredicateOperator::LessThanOrEq,
2117 Datum::date_from_str(value)?,
2118 ),
2119 Some("name <= 47"),
2120 )?;
2121
2122 fixture.assert_projection(
2123 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
2124 Some("name >= 48"),
2125 )?;
2126
2127 fixture.assert_projection(
2128 &fixture.binary_predicate(
2129 PredicateOperator::GreaterThanOrEq,
2130 Datum::date_from_str(value)?,
2131 ),
2132 Some("name >= 47"),
2133 )?;
2134
2135 fixture.assert_projection(
2136 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
2137 Some("name = 47"),
2138 )?;
2139
2140 fixture.assert_projection(
2141 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
2142 None,
2143 )?;
2144
2145 fixture.assert_projection(
2146 &fixture.set_predicate(PredicateOperator::In, vec![
2147 Datum::date_from_str(value)?,
2148 Datum::date_from_str(another)?,
2149 ]),
2150 Some("name IN (47, 46)"),
2151 )?;
2152
2153 fixture.assert_projection(
2154 &fixture.set_predicate(PredicateOperator::NotIn, vec![
2155 Datum::date_from_str(value)?,
2156 Datum::date_from_str(another)?,
2157 ]),
2158 None,
2159 )?;
2160
2161 Ok(())
2162 }
2163
2164 #[test]
2165 fn test_projection_date_year_negative_lower_bound() -> Result<()> {
2166 let value = "1970-01-01";
2168 let another = "1969-12-31";
2170
2171 let fixture = TestProjectionFixture::new(
2172 Transform::Year,
2173 "name",
2174 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
2175 );
2176
2177 fixture.assert_projection(
2178 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
2179 Some("name <= 0"),
2180 )?;
2181
2182 fixture.assert_projection(
2183 &fixture.binary_predicate(
2184 PredicateOperator::LessThanOrEq,
2185 Datum::date_from_str(value)?,
2186 ),
2187 Some("name <= 0"),
2188 )?;
2189
2190 fixture.assert_projection(
2191 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
2192 Some("name >= 0"),
2193 )?;
2194
2195 fixture.assert_projection(
2196 &fixture.binary_predicate(
2197 PredicateOperator::GreaterThanOrEq,
2198 Datum::date_from_str(value)?,
2199 ),
2200 Some("name >= 0"),
2201 )?;
2202
2203 fixture.assert_projection(
2204 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
2205 Some("name = 0"),
2206 )?;
2207
2208 fixture.assert_projection(
2209 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
2210 None,
2211 )?;
2212
2213 fixture.assert_projection(
2214 &fixture.set_predicate(PredicateOperator::In, vec![
2215 Datum::date_from_str(value)?,
2216 Datum::date_from_str(another)?,
2217 ]),
2218 Some("name IN (0, -1)"),
2219 )?;
2220
2221 fixture.assert_projection(
2222 &fixture.set_predicate(PredicateOperator::NotIn, vec![
2223 Datum::date_from_str(value)?,
2224 Datum::date_from_str(another)?,
2225 ]),
2226 None,
2227 )?;
2228
2229 Ok(())
2230 }
2231
2232 #[test]
2233 fn test_projection_date_year_lower_bound() -> Result<()> {
2234 let value = "2017-01-01";
2236 let another = "2016-12-31";
2238
2239 let fixture = TestProjectionFixture::new(
2240 Transform::Year,
2241 "name",
2242 NestedField::required(1, "value", Type::Primitive(PrimitiveType::Date)),
2243 );
2244
2245 fixture.assert_projection(
2246 &fixture.binary_predicate(PredicateOperator::LessThan, Datum::date_from_str(value)?),
2247 Some("name <= 46"),
2248 )?;
2249
2250 fixture.assert_projection(
2251 &fixture.binary_predicate(
2252 PredicateOperator::LessThanOrEq,
2253 Datum::date_from_str(value)?,
2254 ),
2255 Some("name <= 47"),
2256 )?;
2257
2258 fixture.assert_projection(
2259 &fixture.binary_predicate(PredicateOperator::GreaterThan, Datum::date_from_str(value)?),
2260 Some("name >= 47"),
2261 )?;
2262
2263 fixture.assert_projection(
2264 &fixture.binary_predicate(
2265 PredicateOperator::GreaterThanOrEq,
2266 Datum::date_from_str(value)?,
2267 ),
2268 Some("name >= 47"),
2269 )?;
2270
2271 fixture.assert_projection(
2272 &fixture.binary_predicate(PredicateOperator::Eq, Datum::date_from_str(value)?),
2273 Some("name = 47"),
2274 )?;
2275
2276 fixture.assert_projection(
2277 &fixture.binary_predicate(PredicateOperator::NotEq, Datum::date_from_str(value)?),
2278 None,
2279 )?;
2280
2281 fixture.assert_projection(
2282 &fixture.set_predicate(PredicateOperator::In, vec![
2283 Datum::date_from_str(value)?,
2284 Datum::date_from_str(another)?,
2285 ]),
2286 Some("name IN (47, 46)"),
2287 )?;
2288
2289 fixture.assert_projection(
2290 &fixture.set_predicate(PredicateOperator::NotIn, vec![
2291 Datum::date_from_str(value)?,
2292 Datum::date_from_str(another)?,
2293 ]),
2294 None,
2295 )?;
2296
2297 Ok(())
2298 }
2299
2300 #[test]
2301 fn test_transform_years() {
2302 let year = super::Year;
2303
2304 let ori_date = vec![
2306 NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
2307 NaiveDate::from_ymd_opt(2000, 1, 1).unwrap(),
2308 NaiveDate::from_ymd_opt(2030, 1, 1).unwrap(),
2309 NaiveDate::from_ymd_opt(2060, 1, 1).unwrap(),
2310 NaiveDate::from_ymd_opt(1969, 1, 1).unwrap(),
2311 ];
2312 let date_array: ArrayRef = Arc::new(Date32Array::from(
2313 ori_date
2314 .into_iter()
2315 .map(|date| {
2316 date.signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap())
2317 .num_days() as i32
2318 })
2319 .collect::<Vec<i32>>(),
2320 ));
2321 let res = year.transform(date_array).unwrap();
2322 let res = res.as_any().downcast_ref::<Int32Array>().unwrap();
2323 assert_eq!(res.len(), 5);
2324 assert_eq!(res.value(0), 0);
2325 assert_eq!(res.value(1), 30);
2326 assert_eq!(res.value(2), 60);
2327 assert_eq!(res.value(3), 90);
2328 assert_eq!(res.value(4), -1);
2329
2330 let ori_timestamp = vec![
2332 NaiveDateTime::parse_from_str("1970-01-01 12:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2333 .unwrap(),
2334 NaiveDateTime::parse_from_str("2000-01-01 19:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2335 .unwrap(),
2336 NaiveDateTime::parse_from_str("2030-01-01 10:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2337 .unwrap(),
2338 NaiveDateTime::parse_from_str("2060-01-01 11:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2339 .unwrap(),
2340 NaiveDateTime::parse_from_str("1969-01-01 00:00:00.00", "%Y-%m-%d %H:%M:%S.%f")
2341 .unwrap(),
2342 ];
2343 let date_array: ArrayRef = Arc::new(TimestampMicrosecondArray::from(
2344 ori_timestamp
2345 .into_iter()
2346 .map(|timestamp| {
2347 timestamp
2348 .signed_duration_since(
2349 NaiveDateTime::parse_from_str(
2350 "1970-01-01 00:00:00.0",
2351 "%Y-%m-%d %H:%M:%S.%f",
2352 )
2353 .unwrap(),
2354 )
2355 .num_microseconds()
2356 .unwrap()
2357 })
2358 .collect::<Vec<i64>>(),
2359 ));
2360 let res = year.transform(date_array).unwrap();
2361 let res = res.as_any().downcast_ref::<Int32Array>().unwrap();
2362 assert_eq!(res.len(), 5);
2363 assert_eq!(res.value(0), 0);
2364 assert_eq!(res.value(1), 30);
2365 assert_eq!(res.value(2), 60);
2366 assert_eq!(res.value(3), 90);
2367 assert_eq!(res.value(4), -1);
2368 }
2369
2370 fn test_timestamp_and_tz_transform(
2371 time: &str,
2372 transform: &BoxedTransformFunction,
2373 expect: Datum,
2374 ) {
2375 let timestamp = Datum::timestamp_from_str(time).unwrap();
2376 let timestamp_tz = Datum::timestamptz_from_str(time.to_owned() + " +00:00").unwrap();
2377 let res = transform.transform_literal(×tamp).unwrap().unwrap();
2378 assert_eq!(res, expect);
2379 let res = transform.transform_literal(×tamp_tz).unwrap().unwrap();
2380 assert_eq!(res, expect);
2381 }
2382
2383 fn test_timestamp_and_tz_transform_using_i64(
2384 time: i64,
2385 transform: &BoxedTransformFunction,
2386 expect: Datum,
2387 ) {
2388 let timestamp = Datum::timestamp_micros(time);
2389 let timestamp_tz = Datum::timestamptz_micros(time);
2390 let res = transform.transform_literal(×tamp).unwrap().unwrap();
2391 assert_eq!(res, expect);
2392 let res = transform.transform_literal(×tamp_tz).unwrap().unwrap();
2393 assert_eq!(res, expect);
2394 }
2395
2396 fn test_date(date: i32, transform: &BoxedTransformFunction, expect: Datum) {
2397 let date = Datum::date(date);
2398 let res = transform.transform_literal(&date).unwrap().unwrap();
2399 assert_eq!(res, expect);
2400 }
2401
2402 fn test_timestamp_ns_and_tz_transform(
2403 time: &str,
2404 transform: &BoxedTransformFunction,
2405 expect: Datum,
2406 ) {
2407 let timestamp_ns = Datum::timestamp_from_str(time).unwrap();
2408 let timestamptz_ns = Datum::timestamptz_from_str(time.to_owned() + " +00:00").unwrap();
2409 let res = transform.transform_literal(×tamp_ns).unwrap().unwrap();
2410 assert_eq!(res, expect);
2411 let res = transform
2412 .transform_literal(×tamptz_ns)
2413 .unwrap()
2414 .unwrap();
2415 assert_eq!(res, expect);
2416 }
2417
2418 fn test_timestamp_ns_and_tz_transform_using_i64(
2419 time: i64,
2420 transform: &BoxedTransformFunction,
2421 expect: Datum,
2422 ) {
2423 let timestamp_ns = Datum::timestamp_nanos(time);
2424 let timestamptz_ns = Datum::timestamptz_nanos(time);
2425 let res = transform.transform_literal(×tamp_ns).unwrap().unwrap();
2426 assert_eq!(res, expect);
2427 let res = transform
2428 .transform_literal(×tamptz_ns)
2429 .unwrap()
2430 .unwrap();
2431 assert_eq!(res, expect);
2432 }
2433
2434 #[test]
2435 fn test_transform_year_literal() {
2436 let year = Box::new(super::Year) as BoxedTransformFunction;
2437
2438 test_date(18628, &year, Datum::int(2021 - super::UNIX_EPOCH_YEAR));
2440 test_date(-365, &year, Datum::int(-1));
2441
2442 test_timestamp_and_tz_transform_using_i64(
2444 186280000000,
2445 &year,
2446 Datum::int(1970 - super::UNIX_EPOCH_YEAR),
2447 );
2448 test_timestamp_and_tz_transform("1969-01-01T00:00:00.000000", &year, Datum::int(-1));
2449
2450 test_timestamp_ns_and_tz_transform_using_i64(
2452 186280000000,
2453 &year,
2454 Datum::int(1970 - super::UNIX_EPOCH_YEAR),
2455 );
2456 test_timestamp_ns_and_tz_transform("1969-01-01T00:00:00.000000", &year, Datum::int(-1));
2457 }
2458
2459 #[test]
2460 fn test_transform_months() {
2461 let month = super::Month;
2462
2463 let ori_date = vec![
2465 NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
2466 NaiveDate::from_ymd_opt(2000, 4, 1).unwrap(),
2467 NaiveDate::from_ymd_opt(2030, 7, 1).unwrap(),
2468 NaiveDate::from_ymd_opt(2060, 10, 1).unwrap(),
2469 NaiveDate::from_ymd_opt(1969, 12, 1).unwrap(),
2470 ];
2471 let date_array: ArrayRef = Arc::new(Date32Array::from(
2472 ori_date
2473 .into_iter()
2474 .map(|date| {
2475 date.signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap())
2476 .num_days() as i32
2477 })
2478 .collect::<Vec<i32>>(),
2479 ));
2480 let res = month.transform(date_array).unwrap();
2481 let res = res.as_any().downcast_ref::<Int32Array>().unwrap();
2482 assert_eq!(res.len(), 5);
2483 assert_eq!(res.value(0), 0);
2484 assert_eq!(res.value(1), 30 * 12 + 3);
2485 assert_eq!(res.value(2), 60 * 12 + 6);
2486 assert_eq!(res.value(3), 90 * 12 + 9);
2487 assert_eq!(res.value(4), -1);
2488
2489 let ori_timestamp = vec![
2491 NaiveDateTime::parse_from_str("1970-01-01 12:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2492 .unwrap(),
2493 NaiveDateTime::parse_from_str("2000-04-01 19:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2494 .unwrap(),
2495 NaiveDateTime::parse_from_str("2030-07-01 10:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2496 .unwrap(),
2497 NaiveDateTime::parse_from_str("2060-10-01 11:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2498 .unwrap(),
2499 NaiveDateTime::parse_from_str("1969-12-01 00:00:00.00", "%Y-%m-%d %H:%M:%S.%f")
2500 .unwrap(),
2501 ];
2502 let date_array: ArrayRef = Arc::new(TimestampMicrosecondArray::from(
2503 ori_timestamp
2504 .into_iter()
2505 .map(|timestamp| {
2506 timestamp
2507 .signed_duration_since(
2508 NaiveDateTime::parse_from_str(
2509 "1970-01-01 00:00:00.0",
2510 "%Y-%m-%d %H:%M:%S.%f",
2511 )
2512 .unwrap(),
2513 )
2514 .num_microseconds()
2515 .unwrap()
2516 })
2517 .collect::<Vec<i64>>(),
2518 ));
2519 let res = month.transform(date_array).unwrap();
2520 let res = res.as_any().downcast_ref::<Int32Array>().unwrap();
2521 assert_eq!(res.len(), 5);
2522 assert_eq!(res.value(0), 0);
2523 assert_eq!(res.value(1), 30 * 12 + 3);
2524 assert_eq!(res.value(2), 60 * 12 + 6);
2525 assert_eq!(res.value(3), 90 * 12 + 9);
2526 assert_eq!(res.value(4), -1);
2527 }
2528
2529 #[test]
2530 fn test_transform_month_literal() {
2531 let month = Box::new(super::Month) as BoxedTransformFunction;
2532
2533 test_date(
2535 18628,
2536 &month,
2537 Datum::int((2021 - super::UNIX_EPOCH_YEAR) * 12),
2538 );
2539 test_date(-31, &month, Datum::int(-1));
2540
2541 test_timestamp_and_tz_transform_using_i64(
2543 186280000000,
2544 &month,
2545 Datum::int((1970 - super::UNIX_EPOCH_YEAR) * 12),
2546 );
2547 test_timestamp_and_tz_transform("1969-12-01T23:00:00.000000", &month, Datum::int(-1));
2548 test_timestamp_and_tz_transform("2017-12-01T00:00:00.000000", &month, Datum::int(575));
2549 test_timestamp_and_tz_transform("1970-01-01T00:00:00.000000", &month, Datum::int(0));
2550 test_timestamp_and_tz_transform("1969-12-31T00:00:00.000000", &month, Datum::int(-1));
2551
2552 test_timestamp_ns_and_tz_transform_using_i64(
2554 186280000000,
2555 &month,
2556 Datum::int((1970 - super::UNIX_EPOCH_YEAR) * 12),
2557 );
2558 test_timestamp_ns_and_tz_transform("1969-12-01T23:00:00.000000", &month, Datum::int(-1));
2559 test_timestamp_ns_and_tz_transform("2017-12-01T00:00:00.000000", &month, Datum::int(575));
2560 test_timestamp_ns_and_tz_transform("1970-01-01T00:00:00.000000", &month, Datum::int(0));
2561 test_timestamp_ns_and_tz_transform("1969-12-31T00:00:00.000000", &month, Datum::int(-1));
2562 }
2563
2564 #[test]
2565 fn test_transform_days() {
2566 let day = super::Day;
2567 let ori_date = vec![
2568 NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
2569 NaiveDate::from_ymd_opt(2000, 4, 1).unwrap(),
2570 NaiveDate::from_ymd_opt(2030, 7, 1).unwrap(),
2571 NaiveDate::from_ymd_opt(2060, 10, 1).unwrap(),
2572 NaiveDate::from_ymd_opt(1969, 12, 31).unwrap(),
2573 ];
2574 let expect_day = ori_date
2575 .clone()
2576 .into_iter()
2577 .map(|data| {
2578 data.signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap())
2579 .num_days() as i32
2580 })
2581 .collect::<Vec<i32>>();
2582
2583 let date_array: ArrayRef = Arc::new(Date32Array::from(
2585 ori_date
2586 .into_iter()
2587 .map(|date| {
2588 date.signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap())
2589 .num_days() as i32
2590 })
2591 .collect::<Vec<i32>>(),
2592 ));
2593 let res = day.transform(date_array).unwrap();
2594 let res = res.as_any().downcast_ref::<Date32Array>().unwrap();
2595 assert_eq!(res.len(), 5);
2596 assert_eq!(res.value(0), expect_day[0]);
2597 assert_eq!(res.value(1), expect_day[1]);
2598 assert_eq!(res.value(2), expect_day[2]);
2599 assert_eq!(res.value(3), expect_day[3]);
2600 assert_eq!(res.value(4), -1);
2601
2602 let ori_timestamp = vec![
2604 NaiveDateTime::parse_from_str("1970-01-01 12:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2605 .unwrap(),
2606 NaiveDateTime::parse_from_str("2000-04-01 19:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2607 .unwrap(),
2608 NaiveDateTime::parse_from_str("2030-07-01 10:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2609 .unwrap(),
2610 NaiveDateTime::parse_from_str("2060-10-01 11:30:42.123", "%Y-%m-%d %H:%M:%S.%f")
2611 .unwrap(),
2612 NaiveDateTime::parse_from_str("1969-12-31 00:00:00.00", "%Y-%m-%d %H:%M:%S.%f")
2613 .unwrap(),
2614 ];
2615 let date_array: ArrayRef = Arc::new(TimestampMicrosecondArray::from(
2616 ori_timestamp
2617 .into_iter()
2618 .map(|timestamp| {
2619 timestamp
2620 .signed_duration_since(
2621 NaiveDateTime::parse_from_str(
2622 "1970-01-01 00:00:00.0",
2623 "%Y-%m-%d %H:%M:%S.%f",
2624 )
2625 .unwrap(),
2626 )
2627 .num_microseconds()
2628 .unwrap()
2629 })
2630 .collect::<Vec<i64>>(),
2631 ));
2632 let res = day.transform(date_array).unwrap();
2633 let res = res.as_any().downcast_ref::<Date32Array>().unwrap();
2634 assert_eq!(res.len(), 5);
2635 assert_eq!(res.value(0), expect_day[0]);
2636 assert_eq!(res.value(1), expect_day[1]);
2637 assert_eq!(res.value(2), expect_day[2]);
2638 assert_eq!(res.value(3), expect_day[3]);
2639 assert_eq!(res.value(4), -1);
2640 }
2641
2642 #[test]
2643 fn test_transform_days_literal() {
2644 let day = Box::new(super::Day) as BoxedTransformFunction;
2645 test_date(18628, &day, Datum::date(18628));
2647 test_date(-31, &day, Datum::date(-31));
2648
2649 test_timestamp_and_tz_transform_using_i64(1512151975038194, &day, Datum::date(17501));
2651 test_timestamp_and_tz_transform_using_i64(-115200000000, &day, Datum::date(-2));
2652 test_timestamp_and_tz_transform("2017-12-01T10:30:42.123000", &day, Datum::date(17501));
2653
2654 test_timestamp_ns_and_tz_transform_using_i64(1512151975038194, &day, Datum::date(17));
2656 test_timestamp_ns_and_tz_transform_using_i64(-115200000000, &day, Datum::date(-1));
2657 test_timestamp_ns_and_tz_transform("2017-12-01T10:30:42.123000", &day, Datum::date(17501));
2658 }
2659
2660 #[test]
2661 fn test_transform_hours() {
2662 let hour = super::Hour;
2663 let ori_timestamp = vec![
2664 NaiveDateTime::parse_from_str("1970-01-01 19:01:23.123", "%Y-%m-%d %H:%M:%S.%f")
2665 .unwrap(),
2666 NaiveDateTime::parse_from_str("2000-03-01 12:01:23.123", "%Y-%m-%d %H:%M:%S.%f")
2667 .unwrap(),
2668 NaiveDateTime::parse_from_str("2030-10-02 10:01:23.123", "%Y-%m-%d %H:%M:%S.%f")
2669 .unwrap(),
2670 NaiveDateTime::parse_from_str("2060-09-01 05:03:23.123", "%Y-%m-%d %H:%M:%S.%f")
2671 .unwrap(),
2672 NaiveDateTime::parse_from_str("1969-12-31 23:00:00.00", "%Y-%m-%d %H:%M:%S.%f")
2673 .unwrap(),
2674 ];
2675 let expect_hour = ori_timestamp
2676 .clone()
2677 .into_iter()
2678 .map(|timestamp| {
2679 timestamp
2680 .signed_duration_since(
2681 NaiveDateTime::parse_from_str(
2682 "1970-01-01 00:00:0.0",
2683 "%Y-%m-%d %H:%M:%S.%f",
2684 )
2685 .unwrap(),
2686 )
2687 .num_hours() as i32
2688 })
2689 .collect::<Vec<i32>>();
2690
2691 let date_array: ArrayRef = Arc::new(TimestampMicrosecondArray::from(
2693 ori_timestamp
2694 .into_iter()
2695 .map(|timestamp| {
2696 timestamp
2697 .signed_duration_since(
2698 NaiveDateTime::parse_from_str(
2699 "1970-01-01 00:00:0.0",
2700 "%Y-%m-%d %H:%M:%S.%f",
2701 )
2702 .unwrap(),
2703 )
2704 .num_microseconds()
2705 .unwrap()
2706 })
2707 .collect::<Vec<i64>>(),
2708 ));
2709 let res = hour.transform(date_array).unwrap();
2710 let res = res.as_any().downcast_ref::<Int32Array>().unwrap();
2711 assert_eq!(res.len(), 5);
2712 assert_eq!(res.value(0), expect_hour[0]);
2713 assert_eq!(res.value(1), expect_hour[1]);
2714 assert_eq!(res.value(2), expect_hour[2]);
2715 assert_eq!(res.value(3), expect_hour[3]);
2716 assert_eq!(res.value(4), -1);
2717 }
2718
2719 #[test]
2720 fn test_transform_hours_literal() {
2721 let hour = Box::new(super::Hour) as BoxedTransformFunction;
2722
2723 test_timestamp_and_tz_transform("2017-12-01T18:00:00.000000", &hour, Datum::int(420042));
2724 test_timestamp_and_tz_transform("1970-01-01T22:01:01.000000", &hour, Datum::int(22));
2725 test_timestamp_and_tz_transform("1969-12-31T23:00:00.000000", &hour, Datum::int(-1));
2726 test_timestamp_and_tz_transform("1969-12-31T22:01:01.000000", &hour, Datum::int(-2));
2727 test_timestamp_and_tz_transform("0022-05-01T22:01:01.000000", &hour, Datum::int(-17072906));
2728
2729 test_timestamp_ns_and_tz_transform(
2731 "2017-12-01T18:00:00.0000000000",
2732 &hour,
2733 Datum::int(420042),
2734 );
2735 test_timestamp_ns_and_tz_transform("1969-12-31T23:00:00.0000000000", &hour, Datum::int(-1));
2736 test_timestamp_ns_and_tz_transform(
2737 "1900-05-01T22:01:01.0000000000",
2738 &hour,
2739 Datum::int(-610706),
2740 );
2741 }
2742}