use arrow_array::RecordBatch;
use reifydb_core::{
expression::{Expression, ExtendExpression},
value::column::factory,
};
use crate::common::{Env, Frozen, and, batch, between, column, compare, frag, list, map, number, strings, text, tuple};
fn input() -> RecordBatch {
batch(vec![
factory::int4("a", [1, 2]),
factory::utf8("s", ["x", "y"]),
factory::int4_optional("n", [Some(5), None]),
])
}
#[test]
fn every_constructor_shape_matches_the_old_path() {
let mut frozen = Frozen::load("every_constructor_shape_matches_the_old_path");
let env = Env::new();
for expression in [
tuple(vec![column("a")]),
tuple(vec![column("a"), column("s")]),
list(vec![column("a"), number("1")]),
list(vec![text("x")]),
map(vec![column("s")]),
] {
let lowered = env.lowered(&expression, input()).unwrap();
let old = frozen.old(&env, &expression, input()).unwrap();
assert_eq!(lowered.0, old.0, "field of {expression:?}");
assert_eq!(strings(&lowered), strings(&old), "values of {expression:?}");
}
}
#[test]
fn an_empty_list_matches_the_old_path_on_one_row() {
let mut frozen = Frozen::inline(&[
"Field { name: \"[..]\", data_type: LargeBinary, metadata: {\"ARROW:extension:name\": \"reifydb.any\"} } [\"[]\"]",
]);
let env = Env::new();
let one = batch(vec![factory::int4("a", [1])]);
let expression = list(vec![]);
let lowered = env.lowered(&expression, one.clone()).unwrap();
assert_eq!(strings(&lowered), strings(&frozen.old(&env, &expression, one).unwrap()));
assert_eq!(strings(&env.lowered(&expression, input()).unwrap()).len(), 2, "one empty list per row");
}
#[test]
fn a_map_of_several_columns_errors_like_the_old_path() {
let mut frozen =
Frozen::inline(&["RUNTIME_010 \"\" expression produces more than one column where one is required []"]);
let env = Env::new();
let expression = map(vec![column("a"), column("s")]);
let lowered = env.lowered(&expression, input()).unwrap_err();
assert_eq!(lowered.code, frozen.old(&env, &expression, input()).unwrap_err().code);
}
#[test]
fn a_constructor_lowers_with_the_rest_of_its_expression() {
let env = Env::new();
let guard = || between(column("n"), number("0"), number("10"));
let extend = Expression::Extend(ExtendExpression {
expressions: vec![guard()],
fragment: frag("extend"),
});
for wrapped in [tuple(vec![guard()]), map(vec![guard()]), extend] {
let lowered = env.lowered(&and(guard(), wrapped.clone()), input()).unwrap();
assert_eq!(strings(&lowered), vec!["true", "none"], "{wrapped:?}");
}
let listed = and(guard(), compare("==", list(vec![guard()]), list(vec![guard()])));
assert_ne!(env.lowered(&listed, input()).unwrap_err().code, "OPERATOR_028", "a list must not fall back");
}