risingwave_sqlparser/parser_v2/
expr.rsuse winnow::combinator::{alt, cut_err, opt, preceded, repeat, seq, trace};
use winnow::error::ContextError;
use winnow::{PResult, Parser};
use super::{data_type, token, ParserExt, TokenStream};
use crate::ast::Expr;
use crate::keywords::Keyword;
use crate::parser::Precedence;
use crate::tokenizer::Token;
fn expr_parse<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
trace("expr", |input: &mut S| {
input.parse_v1(|parser| parser.parse_expr())
})
.parse_next(input)
}
fn subexpr<S>(precedence: Precedence) -> impl Parser<S, Expr, ContextError>
where
S: TokenStream,
{
trace("subexpr", move |input: &mut S| {
input.parse_v1(|parser| parser.parse_subexpr(precedence))
})
}
pub fn expr_case<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let parse = (
opt(expr_parse),
repeat(
1..,
(
Keyword::WHEN,
cut_err(expr_parse),
cut_err(Keyword::THEN),
cut_err(expr_parse),
),
),
opt(preceded(Keyword::ELSE, cut_err(expr_parse))),
cut_err(Keyword::END),
)
.map(|(operand, branches, else_result, _)| {
let branches: Vec<_> = branches;
let (conditions, results) = branches.into_iter().map(|(_, c, _, t)| (c, t)).unzip();
Expr::Case {
operand: operand.map(Box::new),
conditions,
results,
else_result: else_result.map(Box::new),
}
});
trace("expr_case", parse).parse_next(input)
}
pub fn expr_cast<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let parse = cut_err(seq! {Expr::Cast {
_: Token::LParen,
expr: expr_parse.map(Box::new),
_: Keyword::AS,
data_type: data_type,
_: Token::RParen,
}});
trace("expr_cast", parse).parse_next(input)
}
pub fn expr_try_cast<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let parse = cut_err(seq! {Expr::TryCast {
_: Token::LParen,
expr: expr_parse.map(Box::new),
_: Keyword::AS,
data_type: data_type,
_: Token::RParen,
}});
trace("expr_try_cast", parse).parse_next(input)
}
pub fn expr_extract<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let mut date_time_field = token
.verify_map(|token| match token.token {
Token::Word(w) => Some(w.value.to_uppercase()),
Token::SingleQuotedString(s) => Some(s.to_uppercase()),
_ => None,
})
.expect("date/time field");
let parse = cut_err(seq! {Expr::Extract {
_: Token::LParen,
field: date_time_field,
_: Keyword::FROM,
expr: expr_parse.map(Box::new),
_: Token::RParen,
}});
trace("expr_extract", parse).parse_next(input)
}
pub fn expr_substring<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let mut substring_from = opt(preceded(
alt((Token::Comma.void(), Keyword::FROM.void())),
cut_err(expr_parse).map(Box::new),
));
let mut substring_for = opt(preceded(
alt((Token::Comma.void(), Keyword::FOR.void())),
cut_err(expr_parse).map(Box::new),
));
let parse = cut_err(seq! {Expr::Substring {
_: Token::LParen,
expr: expr_parse.map(Box::new),
substring_from: substring_from,
substring_for: substring_for,
_: Token::RParen,
}});
trace("expr_substring", parse).parse_next(input)
}
pub fn expr_position<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let parse = cut_err(seq! {Expr::Position {
_: Token::LParen,
substring: subexpr(Precedence::Between).map(Box::new),
_: Keyword::IN,
string: subexpr(Precedence::Between).map(Box::new),
_: Token::RParen,
}});
trace("expr_position", parse).parse_next(input)
}
pub fn expr_overlay<S>(input: &mut S) -> PResult<Expr>
where
S: TokenStream,
{
let mut count_parse = opt(preceded(
Keyword::FOR.void(),
cut_err(expr_parse).map(Box::new),
));
let parse = cut_err(seq! {Expr::Overlay {
_: Token::LParen,
expr: expr_parse.map(Box::new),
_: Keyword::PLACING,
new_substring: expr_parse.map(Box::new),
_: Keyword::FROM,
start: expr_parse.map(Box::new),
count: count_parse,
_: Token::RParen,
}});
trace("expr_overlay", parse).parse_next(input)
}