use crate::{Boolean, expression::Expression, lower::LowerCtx, query::LowerFromItem};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum JoinKind {
Left,
Right,
Inner,
}
pub struct JoinOn<L, R> {
pub(crate) left: L,
pub(crate) right: R,
}
pub trait LowerJoin {
fn lower_join(self, kind: JoinKind, ctx: &mut LowerCtx);
}
impl<L, R> LowerJoin for JoinOn<L, R>
where
L: LowerFromItem,
R: Expression,
R::Type: Boolean,
{
fn lower_join(self, kind: JoinKind, ctx: &mut LowerCtx) {
let start = ctx.instrs.len();
self.left.lower_from_item(ctx);
let lhs = ctx.instrs.len() - start;
let rhs = self.right.lower(ctx);
ctx.instrs.push(crate::RpnInstr::Join { kind, lhs, rhs });
}
}
pub trait OnJoin: Sized {
fn on<E>(self, e: E) -> JoinOn<Self, E>
where
E: Expression,
E::Type: Boolean,
{
JoinOn {
left: self,
right: e,
}
}
}
impl<T> OnJoin for T where T: LowerFromItem {}