use std::cmp::Ordering;
use crate::expressions::{
BinaryPredicateOp, ColumnName, Expression, JunctionPredicateOp, OpaquePredicateOpRef, Scalar,
};
use crate::kernel_predicates::{DataSkippingPredicateEvaluator, KernelPredicateEvaluatorDefaults};
use crate::schema::DataType;
#[cfg(test)]
mod tests;
pub(crate) trait ParquetStatsProvider {
fn get_parquet_min_stat(&self, col: &ColumnName, data_type: &DataType) -> Option<Scalar>;
fn get_parquet_max_stat(&self, col: &ColumnName, data_type: &DataType) -> Option<Scalar>;
fn get_parquet_nullcount_stat(&self, col: &ColumnName) -> Option<i64>;
fn get_parquet_rowcount_stat(&self) -> Option<i64>;
}
impl<T: ParquetStatsProvider> DataSkippingPredicateEvaluator for T {
type Output = bool;
type ColumnStat = Scalar;
fn get_min_stat(&self, col: &ColumnName, data_type: &DataType) -> Option<Scalar> {
self.get_parquet_min_stat(col, data_type)
}
fn get_max_stat(&self, col: &ColumnName, data_type: &DataType) -> Option<Scalar> {
self.get_parquet_max_stat(col, data_type)
}
fn get_nullcount_stat(&self, col: &ColumnName) -> Option<Scalar> {
self.get_parquet_nullcount_stat(col).map(Scalar::from)
}
fn get_rowcount_stat(&self) -> Option<Scalar> {
self.get_parquet_rowcount_stat().map(Scalar::from)
}
fn eval_partial_cmp(
&self,
ord: Ordering,
col: Scalar,
val: &Scalar,
inverted: bool,
) -> Option<bool> {
KernelPredicateEvaluatorDefaults::partial_cmp_scalars(ord, &col, val, inverted)
}
fn eval_pred_scalar(&self, val: &Scalar, inverted: bool) -> Option<bool> {
KernelPredicateEvaluatorDefaults::eval_pred_scalar(val, inverted)
}
fn eval_pred_scalar_is_null(&self, val: &Scalar, inverted: bool) -> Option<bool> {
KernelPredicateEvaluatorDefaults::eval_pred_scalar_is_null(val, inverted)
}
fn eval_pred_is_null(&self, col: &ColumnName, inverted: bool) -> Option<bool> {
let safe_to_skip = match inverted {
true => self.get_rowcount_stat()?, false => Scalar::from(0i64), };
Some(self.get_nullcount_stat(col)? != safe_to_skip)
}
fn eval_pred_binary_scalars(
&self,
op: BinaryPredicateOp,
left: &Scalar,
right: &Scalar,
inverted: bool,
) -> Option<bool> {
KernelPredicateEvaluatorDefaults::eval_pred_binary_scalars(op, left, right, inverted)
}
fn eval_pred_opaque(
&self,
op: &OpaquePredicateOpRef,
exprs: &[Expression],
inverted: bool,
) -> Option<bool> {
op.eval_as_data_skipping_predicate(self, exprs, inverted)
}
fn finish_eval_pred_junction(
&self,
op: JunctionPredicateOp,
preds: &mut dyn Iterator<Item = Option<bool>>,
inverted: bool,
) -> Option<bool> {
KernelPredicateEvaluatorDefaults::finish_eval_pred_junction(op, preds, inverted)
}
}