in datafusion/functions/src/datetime/date_bin.rs [536:737]
fn test_date_bin() {
let return_field =
&Field::new("f", DataType::Timestamp(TimeUnit::Nanosecond, None), true);
let mut args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 1,
}))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert!(res.is_ok());
let timestamps = Arc::new((1..6).map(Some).collect::<TimestampNanosecondArray>());
let batch_len = timestamps.len();
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 1,
}))),
ColumnarValue::Array(timestamps),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, batch_len, return_field);
assert!(res.is_ok());
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 1,
}))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert!(res.is_ok());
// stride supports month-day-nano
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalMonthDayNano(Some(
IntervalMonthDayNano {
months: 0,
days: 0,
nanoseconds: 1,
},
))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert!(res.is_ok());
//
// Fallible test cases
//
// invalid number of arguments
args = vec![ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(
IntervalDayTime {
days: 0,
milliseconds: 1,
},
)))];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"Execution error: DATE_BIN expected two or three arguments"
);
// stride: invalid type
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalYearMonth(Some(1))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"Execution error: DATE_BIN expects stride argument to be an INTERVAL but got Interval(YearMonth)"
);
// stride: invalid value
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 0,
}))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"Execution error: DATE_BIN stride must be non-zero"
);
// stride: overflow of day-time interval
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(
IntervalDayTime::MAX,
))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"Execution error: DATE_BIN stride argument is too large"
);
// stride: overflow of month-day-nano interval
args = vec![
ColumnarValue::Scalar(ScalarValue::new_interval_mdn(0, i32::MAX, 1)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"Execution error: DATE_BIN stride argument is too large"
);
// stride: month intervals
args = vec![
ColumnarValue::Scalar(ScalarValue::new_interval_mdn(1, 1, 1)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"This feature is not implemented: DATE_BIN stride does not support combination of month, day and nanosecond intervals"
);
// origin: invalid type
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 1,
}))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampMicrosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"Execution error: DATE_BIN expects origin argument to be a TIMESTAMP with nanosecond precision but got Timestamp(Microsecond, None)"
);
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 1,
}))),
ColumnarValue::Scalar(ScalarValue::TimestampMicrosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert!(res.is_ok());
// unsupported array type for stride
let intervals = Arc::new(
(1..6)
.map(|x| {
Some(IntervalDayTime {
days: 0,
milliseconds: x,
})
})
.collect::<IntervalDayTimeArray>(),
);
args = vec![
ColumnarValue::Array(intervals),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
];
let res = invoke_date_bin_with_args(args, 1, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"This feature is not implemented: DATE_BIN only supports literal values for the stride argument, not arrays"
);
// unsupported array type for origin
let timestamps = Arc::new((1..6).map(Some).collect::<TimestampNanosecondArray>());
let batch_len = timestamps.len();
args = vec![
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(IntervalDayTime {
days: 0,
milliseconds: 1,
}))),
ColumnarValue::Scalar(ScalarValue::TimestampNanosecond(Some(1), None)),
ColumnarValue::Array(timestamps),
];
let res = invoke_date_bin_with_args(args, batch_len, return_field);
assert_eq!(
res.err().unwrap().strip_backtrace(),
"This feature is not implemented: DATE_BIN only supports literal values for the origin argument, not arrays"
);
}