use crate::sql::expression::identifier::SimpleIdentifier;
use crate::sql::query::cte::CTE;
use crate::sql::query::{SQLQuery, SQLQueryExpression};
use crate::write_utils::{blank_line_or_space, maybe_pad, Indent};
use std::fmt;
use std::fmt::{Display, Formatter};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Type {
Union,
UnionAll,
UnionDistinct,
Intersect,
IntersectAll,
IntersectDistinct,
Except,
ExceptAll,
ExceptDistinct,
}
impl Type {
pub fn fmt_indented(&self, f: &mut Formatter<'_>, _indentation: Indent) -> fmt::Result {
match self {
Type::Union => write!(f, "UNION"),
Type::UnionAll => write!(f, "UNION ALL"),
Type::UnionDistinct => write!(f, "UNION DISTINCT"),
Type::Intersect => write!(f, "INTERSECT"),
Type::IntersectAll => write!(f, "INTERSECT ALL"),
Type::IntersectDistinct => write!(f, "INTERSECT DISTINCT"),
Type::Except => write!(f, "EXCEPT"),
Type::ExceptAll => write!(f, "EXCEPT ALL"),
Type::ExceptDistinct => write!(f, "EXCEPT DISTINCT"),
}
}
}
impl Display for Type {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.fmt_indented(f, Indent::default())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SetOperation {
pub typ: Type,
pub left: Box<SQLQueryExpression>,
pub right: Box<SQLQueryExpression>,
pub cte: CTE,
}
impl SetOperation {
pub fn new(left: SQLQueryExpression, right: SQLQueryExpression) -> Self {
Self {
typ: Type::UnionAll,
left: Box::new(left),
right: Box::new(right),
cte: CTE::default(),
}
}
pub fn with_cte(mut self, name: SimpleIdentifier, query: SQLQuery) -> Self {
self.cte = self.cte.with(name, query);
self
}
pub fn fmt_indented(&self, f: &mut Formatter<'_>, indentation: Indent) -> fmt::Result {
self.cte.fmt_indented(f, indentation)?;
maybe_pad(f, indentation)?;
self.left.fmt_indented(f, indentation)?;
blank_line_or_space(f, indentation)?;
maybe_pad(f, indentation)?;
self.typ.fmt_indented(f, indentation)?;
blank_line_or_space(f, indentation)?;
maybe_pad(f, indentation)?;
self.right.fmt_indented(f, indentation)
}
}