use hamelin_lib::sql::expression::identifier::SimpleIdentifier;
use hamelin_lib::sql::expression::literal::{NullLiteral, RowLiteral};
use hamelin_lib::sql::expression::Cast;
use hamelin_lib::sql::expression::{Leaf, SQLExpression};
use hamelin_lib::sql::types::{SQLBaseType, SQLRowType, SQLType};
#[derive(Debug, Clone)]
pub struct RangeBuilder {
pub begin: SQLExpression,
pub begin_type: Option<SQLType>,
pub end: SQLExpression,
pub end_type: Option<SQLType>,
}
impl Default for RangeBuilder {
fn default() -> Self {
RangeBuilder {
begin: SQLExpression::Leaf(Leaf::NullLiteral(NullLiteral::default())),
begin_type: None,
end: SQLExpression::Leaf(Leaf::NullLiteral(NullLiteral::default())),
end_type: None,
}
}
}
impl RangeBuilder {
pub fn from_literal(expression: SQLExpression) -> Option<RangeBuilder> {
if let SQLExpression::Cast(cast) = expression {
if let SQLExpression::RowLiteral(row) = *cast.expression {
if let SQLType::SQLRowType(cast_type) = cast.to {
let mut rb = RangeBuilder::default();
if let Some(begin) = row.values.get(0) {
if let SQLExpression::Leaf(Leaf::NullLiteral(_)) = begin {
} else {
rb = rb.with_begin(
begin.clone(),
cast_type.bindings[&SimpleIdentifier::new("begin")].clone(),
);
}
}
if let Some(end) = row.values.get(1) {
if let SQLExpression::Leaf(Leaf::NullLiteral(_)) = end {
} else {
rb = rb.with_end(
end.clone(),
cast_type.bindings[&SimpleIdentifier::new("end")].clone(),
);
}
}
return Some(rb);
}
}
}
None
}
pub fn with_begin(self, begin: SQLExpression, begin_type: SQLType) -> RangeBuilder {
RangeBuilder {
begin,
begin_type: Some(begin_type.clone()),
end: self.end,
end_type: self.end_type.or(Some(begin_type)),
}
}
pub fn with_end(self, end: SQLExpression, end_type: SQLType) -> RangeBuilder {
RangeBuilder {
begin: self.begin,
begin_type: self.begin_type.or(Some(end_type.clone())),
end,
end_type: Some(end_type),
}
}
pub fn build(self) -> SQLExpression {
let begin_type = self.begin_type.unwrap_or(SQLBaseType::Unknown.into());
let end_type = self.end_type.unwrap_or(SQLBaseType::Unknown.into());
Cast::new(
RowLiteral::new(vec![self.begin, self.end]).into(),
SQLRowType::default()
.with_str("begin", begin_type)
.with_str("end", end_type)
.into(),
)
.into()
}
}