use chrono::{DateTime, Utc};
use datafusion::logical_expr::{Expr, Operator};
use crate::ts_table_provider::{IntervalTruth, ParsedTz, TimePred, UnifiedInterval};
#[derive(Debug, PartialEq)]
pub enum CompiledTimePred {
True,
False,
NonTime,
Unknown,
Cmp {
op: Operator,
ts: DateTime<Utc>,
},
Other,
}
#[derive(Debug, PartialEq, Eq)]
pub enum CompiledIntervalTruth {
AlwaysTrue,
AlwaysFalse,
MaybeTrue,
}
pub fn compile_time_pred_for_tests(expr: &Expr, ts_col: &str) -> CompiledTimePred {
compile_time_pred_for_tests_with_tz(expr, ts_col, None)
}
pub(crate) fn compile_time_pred_for_tests_with_tz(
expr: &Expr,
ts_col: &str,
tz: Option<&ParsedTz>,
) -> CompiledTimePred {
match crate::ts_table_provider::compile_time_pred(expr, ts_col, tz) {
TimePred::True => CompiledTimePred::True,
TimePred::False => CompiledTimePred::False,
TimePred::NonTime => CompiledTimePred::NonTime,
TimePred::Unknown => CompiledTimePred::Unknown,
TimePred::Cmp { op, ts } => CompiledTimePred::Cmp { op, ts },
_ => CompiledTimePred::Other,
}
}
pub fn eval_time_pred_on_segment_for_tests(
expr: &Expr,
ts_col: &str,
seg_min: DateTime<Utc>,
seg_max: DateTime<Utc>,
) -> CompiledIntervalTruth {
eval_time_pred_on_segment_for_tests_with_tz(expr, ts_col, seg_min, seg_max, None)
}
pub(crate) fn eval_time_pred_on_segment_for_tests_with_tz(
expr: &Expr,
ts_col: &str,
seg_min: DateTime<Utc>,
seg_max: DateTime<Utc>,
tz: Option<&ParsedTz>,
) -> CompiledIntervalTruth {
let pred = crate::ts_table_provider::compile_time_pred(expr, ts_col, tz);
match crate::ts_table_provider::eval_time_pred_on_segment(&pred, seg_min, seg_max) {
IntervalTruth::AlwaysTrue => CompiledIntervalTruth::AlwaysTrue,
IntervalTruth::AlwaysFalse => CompiledIntervalTruth::AlwaysFalse,
IntervalTruth::MaybeTrue => CompiledIntervalTruth::MaybeTrue,
}
}
pub fn eval_time_pred_on_segment_for_tests_utc(
expr: &Expr,
ts_col: &str,
seg_min: DateTime<Utc>,
seg_max: DateTime<Utc>,
) -> CompiledIntervalTruth {
eval_time_pred_on_segment_for_tests_with_tz(
expr,
ts_col,
seg_min,
seg_max,
Some(&ParsedTz::Utc),
)
}
pub struct TestInterval {
pub months: i32,
pub days: i32,
pub nanos: i64,
}
pub fn add_interval_for_tests(
dt: DateTime<Utc>,
interval: TestInterval,
sign: i32,
) -> Option<DateTime<Utc>> {
crate::ts_table_provider::add_interval(
dt,
UnifiedInterval {
months: interval.months,
days: interval.days,
nanos: interval.nanos,
},
sign,
)
}