use super::THRESHOLD_INLINE_INLIST;
use datafusion_common::Result;
use datafusion_common::tree_node::{Transformed, TreeNodeRewriter};
use datafusion_expr::Expr;
use datafusion_expr::expr::InList;
pub(super) struct ShortenInListSimplifier {}
impl ShortenInListSimplifier {
pub(super) fn new() -> Self {
Self {}
}
}
impl TreeNodeRewriter for ShortenInListSimplifier {
type Node = Expr;
fn f_up(&mut self, expr: Expr) -> Result<Transformed<Expr>> {
if let Expr::InList(InList {
ref expr,
ref list,
negated,
}) = expr
&& !list.is_empty()
&& (
list.len() == 1
|| list.len() <= THRESHOLD_INLINE_INLIST
&& expr.try_as_col().is_some()
)
{
let first_val = list[0].clone();
if negated {
return Ok(Transformed::yes(list.iter().skip(1).cloned().fold(
(*expr.clone()).not_eq(first_val),
|acc, y| {
acc.and((*expr.clone()).not_eq(y))
},
)));
} else {
return Ok(Transformed::yes(list.iter().skip(1).cloned().fold(
(*expr.clone()).eq(first_val),
|acc, y| {
acc.or((*expr.clone()).eq(y))
},
)));
}
}
Ok(Transformed::no(expr))
}
}