use crate::ast::statements::query::SelectStatement;
use core::range::Range;
use oak_core::source::{SourceBuffer, ToSource};
use std::sync::Arc;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Expression {
Identifier(Identifier),
Literal(Literal),
Binary {
left: Box<Expression>,
op: BinaryOperator,
right: Box<Expression>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
Unary {
op: UnaryOperator,
expr: Box<Expression>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
FunctionCall {
name: Identifier,
args: Vec<Expression>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
Vector {
elements: Vec<Expression>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
InList {
expr: Box<Expression>,
list: Vec<Expression>,
negated: bool,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
Between {
expr: Box<Expression>,
low: Box<Expression>,
high: Box<Expression>,
negated: bool,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
Subquery {
query: Box<SelectStatement>,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
InSubquery {
expr: Box<Expression>,
query: Box<SelectStatement>,
negated: bool,
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
Error {
message: Arc<str>,
#[serde(with = "oak_core::serde_range")]
span: Range<usize>,
},
}
impl Expression {
pub fn span(&self) -> Range<usize> {
match self {
Expression::Identifier(id) => id.span.clone(),
Expression::Literal(lit) => lit.span().clone(),
Expression::Binary { span, .. } => span.clone(),
Expression::Unary { span, .. } => span.clone(),
Expression::FunctionCall { span, .. } => span.clone(),
Expression::InList { span, .. } => span.clone(),
Expression::Between { span, .. } => span.clone(),
Expression::Subquery { span, .. } => span.clone(),
Expression::InSubquery { span, .. } => span.clone(),
Expression::Vector { span, .. } => span.clone(),
Expression::Error { span, .. } => span.clone(),
}
}
}
impl ToSource for Expression {
fn to_source(&self, buffer: &mut SourceBuffer) {
match self {
Expression::Identifier(id) => id.to_source(buffer),
Expression::Literal(lit) => lit.to_source(buffer),
Expression::Binary { left, op, right, .. } => {
left.to_source(buffer);
op.to_source(buffer);
right.to_source(buffer);
}
Expression::Unary { op, expr, .. } => {
op.to_source(buffer);
expr.to_source(buffer);
}
Expression::FunctionCall { name, args, .. } => {
name.to_source(buffer);
buffer.push("(");
for (i, arg) in args.iter().enumerate() {
if i > 0 {
buffer.push(",");
}
arg.to_source(buffer);
}
buffer.push(")");
}
Expression::Vector { elements, .. } => {
buffer.push("[");
for (i, elem) in elements.iter().enumerate() {
if i > 0 {
buffer.push(", ");
}
elem.to_source(buffer);
}
buffer.push("]");
}
Expression::InList { expr, list, negated, .. } => {
expr.to_source(buffer);
if *negated {
buffer.push("NOT");
}
buffer.push("IN");
buffer.push("(");
for (i, item) in list.iter().enumerate() {
if i > 0 {
buffer.push(",");
}
item.to_source(buffer);
}
buffer.push(")");
}
Expression::Between { expr, low, high, negated, .. } => {
expr.to_source(buffer);
if *negated {
buffer.push("NOT");
}
buffer.push("BETWEEN");
low.to_source(buffer);
buffer.push("AND");
high.to_source(buffer);
}
Expression::Subquery { query, .. } => {
buffer.push("(");
query.to_source(buffer);
buffer.push(")");
}
Expression::InSubquery { expr, query, negated, .. } => {
expr.to_source(buffer);
if *negated {
buffer.push("NOT");
}
buffer.push("IN");
buffer.push("(");
query.to_source(buffer);
buffer.push(")");
}
Expression::Error { message, .. } => {
buffer.push("/* EXPR ERROR: ");
buffer.push(message);
buffer.push(" */");
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum BinaryOperator {
Plus,
Minus,
Star,
Slash,
Percent,
And,
Or,
Equal,
NotEqual,
Less,
Greater,
LessEqual,
GreaterEqual,
Like,
}
impl ToSource for BinaryOperator {
fn to_source(&self, buffer: &mut SourceBuffer) {
match self {
BinaryOperator::Plus => buffer.push("+"),
BinaryOperator::Minus => buffer.push("-"),
BinaryOperator::Star => buffer.push("*"),
BinaryOperator::Slash => buffer.push("/"),
BinaryOperator::Percent => buffer.push("%"),
BinaryOperator::And => buffer.push("AND"),
BinaryOperator::Or => buffer.push("OR"),
BinaryOperator::Equal => buffer.push("="),
BinaryOperator::NotEqual => buffer.push("<>"),
BinaryOperator::Less => buffer.push("<"),
BinaryOperator::Greater => buffer.push(">"),
BinaryOperator::LessEqual => buffer.push("<="),
BinaryOperator::GreaterEqual => buffer.push(">="),
BinaryOperator::Like => buffer.push("LIKE"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum UnaryOperator {
Plus,
Minus,
Not,
}
impl ToSource for UnaryOperator {
fn to_source(&self, buffer: &mut SourceBuffer) {
match self {
UnaryOperator::Plus => buffer.push("+"),
UnaryOperator::Minus => buffer.push("-"),
UnaryOperator::Not => buffer.push("NOT"),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Literal {
Number(Arc<str>, #[serde(with = "oak_core::serde_range")] Range<usize>),
String(Arc<str>, #[serde(with = "oak_core::serde_range")] Range<usize>),
Boolean(bool, #[serde(with = "oak_core::serde_range")] Range<usize>),
Null(#[serde(with = "oak_core::serde_range")] Range<usize>),
}
impl Literal {
pub fn span(&self) -> Range<usize> {
match self {
Literal::Number(_, span) => span.clone(),
Literal::String(_, span) => span.clone(),
Literal::Boolean(_, span) => span.clone(),
Literal::Null(span) => span.clone(),
}
}
}
impl ToSource for Literal {
fn to_source(&self, buffer: &mut SourceBuffer) {
match self {
Literal::Number(n, _) => buffer.push(n),
Literal::String(s, _) => {
buffer.push("'");
buffer.push(s);
buffer.push("'");
}
Literal::Boolean(b, _) => buffer.push(if *b { "TRUE" } else { "FALSE" }),
Literal::Null(_) => buffer.push("NULL"),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Identifier {
pub name: Arc<str>,
#[serde(with = "oak_core::serde_range")]
pub span: Range<usize>,
}
impl ToSource for Identifier {
fn to_source(&self, buffer: &mut SourceBuffer) {
buffer.push(&self.name);
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TableName {
pub name: Identifier,
#[serde(with = "oak_core::serde_range")]
pub span: Range<usize>,
}
impl ToSource for TableName {
fn to_source(&self, buffer: &mut SourceBuffer) {
self.name.to_source(buffer);
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ColumnName {
pub name: Identifier,
#[serde(with = "oak_core::serde_range")]
pub span: Range<usize>,
}
impl ToSource for ColumnName {
fn to_source(&self, buffer: &mut SourceBuffer) {
self.name.to_source(buffer);
}
}