use std::{
fmt::{self, Display, Formatter},
str::FromStr,
};
use crate::error::_not_impl_err;
use crate::{DataFusionError, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Hash)]
pub enum JoinType {
Inner,
Left,
Right,
Full,
LeftSemi,
RightSemi,
LeftAnti,
RightAnti,
LeftMark,
}
impl JoinType {
pub fn is_outer(self) -> bool {
self == JoinType::Left || self == JoinType::Right || self == JoinType::Full
}
pub fn swap(&self) -> JoinType {
match self {
JoinType::Inner => JoinType::Inner,
JoinType::Full => JoinType::Full,
JoinType::Left => JoinType::Right,
JoinType::Right => JoinType::Left,
JoinType::LeftSemi => JoinType::RightSemi,
JoinType::RightSemi => JoinType::LeftSemi,
JoinType::LeftAnti => JoinType::RightAnti,
JoinType::RightAnti => JoinType::LeftAnti,
JoinType::LeftMark => {
unreachable!("LeftMark join type does not support swapping")
}
}
}
pub fn supports_swap(&self) -> bool {
matches!(
self,
JoinType::Inner
| JoinType::Left
| JoinType::Right
| JoinType::Full
| JoinType::LeftSemi
| JoinType::RightSemi
| JoinType::LeftAnti
| JoinType::RightAnti
)
}
}
impl Display for JoinType {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let join_type = match self {
JoinType::Inner => "Inner",
JoinType::Left => "Left",
JoinType::Right => "Right",
JoinType::Full => "Full",
JoinType::LeftSemi => "LeftSemi",
JoinType::RightSemi => "RightSemi",
JoinType::LeftAnti => "LeftAnti",
JoinType::RightAnti => "RightAnti",
JoinType::LeftMark => "LeftMark",
};
write!(f, "{join_type}")
}
}
impl FromStr for JoinType {
type Err = DataFusionError;
fn from_str(s: &str) -> Result<Self> {
let s = s.to_uppercase();
match s.as_str() {
"INNER" => Ok(JoinType::Inner),
"LEFT" => Ok(JoinType::Left),
"RIGHT" => Ok(JoinType::Right),
"FULL" => Ok(JoinType::Full),
"LEFTSEMI" => Ok(JoinType::LeftSemi),
"RIGHTSEMI" => Ok(JoinType::RightSemi),
"LEFTANTI" => Ok(JoinType::LeftAnti),
"RIGHTANTI" => Ok(JoinType::RightAnti),
"LEFTMARK" => Ok(JoinType::LeftMark),
_ => _not_impl_err!("The join type {s} does not exist or is not implemented"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Hash)]
pub enum JoinConstraint {
On,
Using,
}
impl Display for JoinSide {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
JoinSide::Left => write!(f, "left"),
JoinSide::Right => write!(f, "right"),
JoinSide::None => write!(f, "none"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum JoinSide {
Left,
Right,
None,
}
impl JoinSide {
pub fn negate(&self) -> Self {
match self {
JoinSide::Left => JoinSide::Right,
JoinSide::Right => JoinSide::Left,
JoinSide::None => JoinSide::None,
}
}
}