use crate::mask::{NullableRowAddrMask, RowAddrMask};
#[derive(Debug)]
pub enum NullableIndexExprResult {
Exact(NullableRowAddrMask),
AtMost(NullableRowAddrMask),
AtLeast(NullableRowAddrMask),
}
impl std::ops::Not for NullableIndexExprResult {
type Output = Self;
fn not(self) -> Self {
match self {
Self::Exact(mask) => Self::Exact(!mask),
Self::AtMost(mask) => Self::AtLeast(!mask),
Self::AtLeast(mask) => Self::AtMost(!mask),
}
}
}
impl std::ops::BitAnd<Self> for NullableIndexExprResult {
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
match (self, rhs) {
(Self::Exact(lhs), Self::Exact(rhs)) => Self::Exact(lhs & rhs),
(Self::Exact(lhs), Self::AtMost(rhs)) | (Self::AtMost(lhs), Self::Exact(rhs)) => {
Self::AtMost(lhs & rhs)
}
(Self::Exact(exact), Self::AtLeast(_)) | (Self::AtLeast(_), Self::Exact(exact)) => {
Self::AtMost(exact)
}
(Self::AtMost(lhs), Self::AtMost(rhs)) => Self::AtMost(lhs & rhs),
(Self::AtLeast(lhs), Self::AtLeast(rhs)) => Self::AtLeast(lhs & rhs),
(Self::AtMost(most), Self::AtLeast(_)) | (Self::AtLeast(_), Self::AtMost(most)) => {
Self::AtMost(most)
}
}
}
}
impl std::ops::BitOr<Self> for NullableIndexExprResult {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
match (self, rhs) {
(Self::Exact(lhs), Self::Exact(rhs)) => Self::Exact(lhs | rhs),
(Self::Exact(lhs), Self::AtMost(rhs)) | (Self::AtMost(rhs), Self::Exact(lhs)) => {
Self::AtMost(lhs | rhs)
}
(Self::Exact(lhs), Self::AtLeast(rhs)) | (Self::AtLeast(rhs), Self::Exact(lhs)) => {
Self::AtLeast(lhs | rhs)
}
(Self::AtMost(lhs), Self::AtMost(rhs)) => Self::AtMost(lhs | rhs),
(Self::AtLeast(lhs), Self::AtLeast(rhs)) => Self::AtLeast(lhs | rhs),
(Self::AtMost(_), Self::AtLeast(least)) | (Self::AtLeast(least), Self::AtMost(_)) => {
Self::AtLeast(least)
}
}
}
}
impl NullableIndexExprResult {
pub fn drop_nulls(self) -> IndexExprResult {
match self {
Self::Exact(mask) => IndexExprResult::Exact(mask.drop_nulls()),
Self::AtMost(mask) => IndexExprResult::AtMost(mask.drop_nulls()),
Self::AtLeast(mask) => IndexExprResult::AtLeast(mask.drop_nulls()),
}
}
}
#[derive(Debug)]
pub enum IndexExprResult {
Exact(RowAddrMask),
AtMost(RowAddrMask),
AtLeast(RowAddrMask),
}
impl IndexExprResult {
pub fn row_addr_mask(&self) -> &RowAddrMask {
match self {
Self::Exact(mask) => mask,
Self::AtMost(mask) => mask,
Self::AtLeast(mask) => mask,
}
}
pub fn discriminant(&self) -> u32 {
match self {
Self::Exact(_) => 0,
Self::AtMost(_) => 1,
Self::AtLeast(_) => 2,
}
}
}