use super::match_condition::AndJoiner;
use super::{EqualJoiner, FilteringJoiner};
use super::{GreaterThanJoiner, GreaterThanOrEqualJoiner, LessThanJoiner, LessThanOrEqualJoiner};
use super::{Joiner, OverlappingJoiner};
mod composite;
mod conjunction;
pub use composite::{
ComposePlans, CompositeEquality, EqualityKeys, EqualityKind, EqualityPlan, ResidualKind,
};
mod executable;
mod hash_scan;
mod mixed_equality;
pub use mixed_equality::EqualityWithResidual;
mod ordered_interval;
pub use executable::{CompileCondition, ExecutablePlan, IndexedPlan};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Strategy {
EquiHash,
OrderedScan,
IntervalNarrow,
Scan,
}
impl Strategy {
#[inline]
pub const fn combine(self, other: Strategy) -> Strategy {
match (self, other) {
(Strategy::EquiHash, _) | (_, Strategy::EquiHash) => Strategy::EquiHash,
(Strategy::OrderedScan, _) | (_, Strategy::OrderedScan) => Strategy::OrderedScan,
(Strategy::IntervalNarrow, _) | (_, Strategy::IntervalNarrow) => {
Strategy::IntervalNarrow
}
(Strategy::Scan, Strategy::Scan) => Strategy::Scan,
}
}
}
pub trait PlannedCondition<Row, C>: Send + Sync {
const STRATEGY: Strategy;
fn check(&self, row: &Row, c: &C) -> bool;
}
#[inline]
pub fn plan_strategy<Row, C, P>(condition: &P) -> Strategy
where
P: PlannedCondition<Row, C>,
{
let _ = condition;
P::STRATEGY
}
impl<Row, C, Fa, Fb, T, Mode> PlannedCondition<Row, C> for EqualJoiner<Fa, Fb, T, Mode>
where
T: PartialEq,
Fa: Fn(&Row) -> T + Send + Sync,
Fb: Fn(&C) -> T + Send + Sync,
{
const STRATEGY: Strategy = Strategy::EquiHash;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for LessThanJoiner<Fa, Fb, T>
where
T: Ord,
Fa: Fn(&Row) -> T + Send + Sync,
Fb: Fn(&C) -> T + Send + Sync,
{
const STRATEGY: Strategy = Strategy::OrderedScan;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for LessThanOrEqualJoiner<Fa, Fb, T>
where
T: Ord,
Fa: Fn(&Row) -> T + Send + Sync,
Fb: Fn(&C) -> T + Send + Sync,
{
const STRATEGY: Strategy = Strategy::OrderedScan;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for GreaterThanJoiner<Fa, Fb, T>
where
T: Ord,
Fa: Fn(&Row) -> T + Send + Sync,
Fb: Fn(&C) -> T + Send + Sync,
{
const STRATEGY: Strategy = Strategy::OrderedScan;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for GreaterThanOrEqualJoiner<Fa, Fb, T>
where
T: Ord,
Fa: Fn(&Row) -> T + Send + Sync,
Fb: Fn(&C) -> T + Send + Sync,
{
const STRATEGY: Strategy = Strategy::OrderedScan;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, Fsa, Fea, Fsb, Feb, T> PlannedCondition<Row, C>
for OverlappingJoiner<Fsa, Fea, Fsb, Feb, T>
where
T: Ord,
Fsa: Fn(&Row) -> T + Send + Sync,
Fea: Fn(&Row) -> T + Send + Sync,
Fsb: Fn(&C) -> T + Send + Sync,
Feb: Fn(&C) -> T + Send + Sync,
{
const STRATEGY: Strategy = Strategy::IntervalNarrow;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, F> PlannedCondition<Row, C> for FilteringJoiner<F>
where
F: Fn(&Row, &C) -> bool + Send + Sync,
{
const STRATEGY: Strategy = Strategy::Scan;
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}
impl<Row, C, J1, J2> PlannedCondition<Row, C> for AndJoiner<J1, J2>
where
J1: PlannedCondition<Row, C> + Joiner<Row, C>,
J2: PlannedCondition<Row, C> + Joiner<Row, C>,
{
const STRATEGY: Strategy = J1::STRATEGY.combine(J2::STRATEGY);
#[inline]
fn check(&self, row: &Row, c: &C) -> bool {
self.matches(row, c)
}
}