in datafusion/common/src/scalar.rs [4647:4854]
fn scalar_eq_array() {
// Validate that eq_array has the same semantics as ScalarValue::eq
macro_rules! make_typed_vec {
($INPUT:expr, $TYPE:ident) => {{
$INPUT
.iter()
.map(|v| v.map(|v| v as $TYPE))
.collect::<Vec<_>>()
}};
}
let bool_vals = vec![Some(true), None, Some(false)];
let f32_vals = vec![Some(-1.0), None, Some(1.0)];
let f64_vals = make_typed_vec!(f32_vals, f64);
let i8_vals = vec![Some(-1), None, Some(1)];
let i16_vals = make_typed_vec!(i8_vals, i16);
let i32_vals = make_typed_vec!(i8_vals, i32);
let i64_vals = make_typed_vec!(i8_vals, i64);
let u8_vals = vec![Some(0), None, Some(1)];
let u16_vals = make_typed_vec!(u8_vals, u16);
let u32_vals = make_typed_vec!(u8_vals, u32);
let u64_vals = make_typed_vec!(u8_vals, u64);
let str_vals = vec![Some("foo"), None, Some("bar")];
/// Test each value in `scalar` with the corresponding element
/// at `array`. Assumes each element is unique (aka not equal
/// with all other indexes)
#[derive(Debug)]
struct TestCase {
array: ArrayRef,
scalars: Vec<ScalarValue>,
}
/// Create a test case for casing the input to the specified array type
macro_rules! make_test_case {
($INPUT:expr, $ARRAY_TY:ident, $SCALAR_TY:ident) => {{
TestCase {
array: Arc::new($INPUT.iter().collect::<$ARRAY_TY>()),
scalars: $INPUT.iter().map(|v| ScalarValue::$SCALAR_TY(*v)).collect(),
}
}};
($INPUT:expr, $ARRAY_TY:ident, $SCALAR_TY:ident, $TZ:expr) => {{
let tz = $TZ;
TestCase {
array: Arc::new($INPUT.iter().collect::<$ARRAY_TY>()),
scalars: $INPUT
.iter()
.map(|v| ScalarValue::$SCALAR_TY(*v, tz.clone()))
.collect(),
}
}};
}
macro_rules! make_str_test_case {
($INPUT:expr, $ARRAY_TY:ident, $SCALAR_TY:ident) => {{
TestCase {
array: Arc::new($INPUT.iter().cloned().collect::<$ARRAY_TY>()),
scalars: $INPUT
.iter()
.map(|v| ScalarValue::$SCALAR_TY(v.map(|v| v.to_string())))
.collect(),
}
}};
}
macro_rules! make_binary_test_case {
($INPUT:expr, $ARRAY_TY:ident, $SCALAR_TY:ident) => {{
TestCase {
array: Arc::new($INPUT.iter().cloned().collect::<$ARRAY_TY>()),
scalars: $INPUT
.iter()
.map(|v| {
ScalarValue::$SCALAR_TY(v.map(|v| v.as_bytes().to_vec()))
})
.collect(),
}
}};
}
/// create a test case for DictionaryArray<$INDEX_TY>
macro_rules! make_str_dict_test_case {
($INPUT:expr, $INDEX_TY:ident) => {{
TestCase {
array: Arc::new(
$INPUT
.iter()
.cloned()
.collect::<DictionaryArray<$INDEX_TY>>(),
),
scalars: $INPUT
.iter()
.map(|v| {
ScalarValue::Dictionary(
Box::new($INDEX_TY::DATA_TYPE),
Box::new(ScalarValue::Utf8(v.map(|v| v.to_string()))),
)
})
.collect(),
}
}};
}
let cases = vec![
make_test_case!(bool_vals, BooleanArray, Boolean),
make_test_case!(f32_vals, Float32Array, Float32),
make_test_case!(f64_vals, Float64Array, Float64),
make_test_case!(i8_vals, Int8Array, Int8),
make_test_case!(i16_vals, Int16Array, Int16),
make_test_case!(i32_vals, Int32Array, Int32),
make_test_case!(i64_vals, Int64Array, Int64),
make_test_case!(u8_vals, UInt8Array, UInt8),
make_test_case!(u16_vals, UInt16Array, UInt16),
make_test_case!(u32_vals, UInt32Array, UInt32),
make_test_case!(u64_vals, UInt64Array, UInt64),
make_str_test_case!(str_vals, StringArray, Utf8),
make_str_test_case!(str_vals, LargeStringArray, LargeUtf8),
make_binary_test_case!(str_vals, BinaryArray, Binary),
make_binary_test_case!(str_vals, LargeBinaryArray, LargeBinary),
make_test_case!(i32_vals, Date32Array, Date32),
make_test_case!(i64_vals, Date64Array, Date64),
make_test_case!(i32_vals, Time32SecondArray, Time32Second),
make_test_case!(i32_vals, Time32MillisecondArray, Time32Millisecond),
make_test_case!(i64_vals, Time64MicrosecondArray, Time64Microsecond),
make_test_case!(i64_vals, Time64NanosecondArray, Time64Nanosecond),
make_test_case!(i64_vals, TimestampSecondArray, TimestampSecond, None),
make_test_case!(
i64_vals,
TimestampSecondArray,
TimestampSecond,
Some("UTC".into())
),
make_test_case!(
i64_vals,
TimestampMillisecondArray,
TimestampMillisecond,
None
),
make_test_case!(
i64_vals,
TimestampMillisecondArray,
TimestampMillisecond,
Some("UTC".into())
),
make_test_case!(
i64_vals,
TimestampMicrosecondArray,
TimestampMicrosecond,
None
),
make_test_case!(
i64_vals,
TimestampMicrosecondArray,
TimestampMicrosecond,
Some("UTC".into())
),
make_test_case!(
i64_vals,
TimestampNanosecondArray,
TimestampNanosecond,
None
),
make_test_case!(
i64_vals,
TimestampNanosecondArray,
TimestampNanosecond,
Some("UTC".into())
),
make_test_case!(i32_vals, IntervalYearMonthArray, IntervalYearMonth),
make_test_case!(i64_vals, IntervalDayTimeArray, IntervalDayTime),
make_str_dict_test_case!(str_vals, Int8Type),
make_str_dict_test_case!(str_vals, Int16Type),
make_str_dict_test_case!(str_vals, Int32Type),
make_str_dict_test_case!(str_vals, Int64Type),
make_str_dict_test_case!(str_vals, UInt8Type),
make_str_dict_test_case!(str_vals, UInt16Type),
make_str_dict_test_case!(str_vals, UInt32Type),
make_str_dict_test_case!(str_vals, UInt64Type),
];
for case in cases {
println!("**** Test Case *****");
let TestCase { array, scalars } = case;
println!("Input array type: {}", array.data_type());
println!("Input scalars: {scalars:#?}");
assert_eq!(array.len(), scalars.len());
for (index, scalar) in scalars.into_iter().enumerate() {
assert!(
scalar.eq_array(&array, index),
"Expected {scalar:?} to be equal to {array:?} at index {index}"
);
// test that all other elements are *not* equal
for other_index in 0..array.len() {
if index != other_index {
assert!(
!scalar.eq_array(&array, other_index),
"Expected {scalar:?} to be NOT equal to {array:?} at index {other_index}"
);
}
}
}
}
}