use once_cell::sync::OnceCell;
use crate::sql::expression::apply::{BinaryOperatorApply, UnaryOperatorApply};
use crate::sql::expression::operator::Operator;
use crate::sql::expression::SQLExpression;
enum PrecedenceEntry {
BinaryPrecedenceEntry(Vec<Operator>),
UnaryPrecedenceEntry(Vec<Operator>),
}
static PRECEDENCE: OnceCell<Vec<PrecedenceEntry>> = OnceCell::new();
pub fn precedence(exp: &SQLExpression) -> Option<usize> {
PRECEDENCE
.get_or_init(|| {
vec![
PrecedenceEntry::UnaryPrecedenceEntry(vec![Operator::Plus, Operator::Minus]),
PrecedenceEntry::BinaryPrecedenceEntry(vec![
Operator::Asterisk,
Operator::Slash,
Operator::Percent,
]),
PrecedenceEntry::BinaryPrecedenceEntry(vec![Operator::Plus, Operator::Minus]),
PrecedenceEntry::BinaryPrecedenceEntry(vec![
Operator::Lt,
Operator::Neq,
Operator::Lt,
Operator::Lte,
Operator::Gt,
Operator::Gte,
]),
PrecedenceEntry::UnaryPrecedenceEntry(vec![Operator::Not]),
PrecedenceEntry::BinaryPrecedenceEntry(vec![Operator::And]),
PrecedenceEntry::BinaryPrecedenceEntry(vec![Operator::Or]),
]
})
.iter()
.enumerate()
.filter(|(_, entry)| match (exp, entry) {
(
SQLExpression::BinaryOperatorApply(BinaryOperatorApply {
operator: this_operator,
..
}),
PrecedenceEntry::BinaryPrecedenceEntry(operators),
) => operators.contains(this_operator),
(
SQLExpression::UnaryOperatorApply(UnaryOperatorApply {
operator: this_operator,
..
}),
PrecedenceEntry::UnaryPrecedenceEntry(operators),
) => operators.contains(this_operator),
_ => false,
})
.map(|(i, _)| i)
.next()
}