risingwave_sqlparser/parser_v2/
expr.rs1use winnow::combinator::{alt, cut_err, opt, preceded, repeat, seq, trace};
13use winnow::error::ContextError;
14use winnow::{ModalParser, ModalResult, Parser};
15
16use super::{ParserExt, TokenStream, data_type, token};
17use crate::ast::Expr;
18use crate::keywords::Keyword;
19use crate::parser::Precedence;
20use crate::tokenizer::Token;
21
22fn expr_parse<S>(input: &mut S) -> ModalResult<Expr>
23where
24 S: TokenStream,
25{
26 trace("expr", |input: &mut S| {
28 input.parse_v1(|parser| parser.parse_expr())
29 })
30 .parse_next(input)
31}
32
33fn subexpr<S>(precedence: Precedence) -> impl ModalParser<S, Expr, ContextError>
34where
35 S: TokenStream,
36{
37 trace("subexpr", move |input: &mut S| {
39 input.parse_v1(|parser| parser.parse_subexpr(precedence))
40 })
41}
42
43pub fn expr_case<S>(input: &mut S) -> ModalResult<Expr>
44where
45 S: TokenStream,
46{
47 let parse = (
48 opt(expr_parse),
49 repeat(
50 1..,
51 (
52 Keyword::WHEN,
53 cut_err(expr_parse),
54 cut_err(Keyword::THEN),
55 cut_err(expr_parse),
56 ),
57 ),
58 opt(preceded(Keyword::ELSE, cut_err(expr_parse))),
59 cut_err(Keyword::END),
60 )
61 .map(|(operand, branches, else_result, _)| {
62 let branches: Vec<_> = branches;
63 let (conditions, results) = branches.into_iter().map(|(_, c, _, t)| (c, t)).unzip();
64 Expr::Case {
65 operand: operand.map(Box::new),
66 conditions,
67 results,
68 else_result: else_result.map(Box::new),
69 }
70 });
71
72 trace("expr_case", parse).parse_next(input)
73}
74
75pub fn expr_cast<S>(input: &mut S) -> ModalResult<Expr>
77where
78 S: TokenStream,
79{
80 let parse = cut_err(seq! {Expr::Cast {
81 _: Token::LParen,
82 expr: expr_parse.map(Box::new),
83 _: Keyword::AS,
84 data_type: data_type,
85 _: Token::RParen,
86 }});
87
88 trace("expr_cast", parse).parse_next(input)
89}
90
91pub fn expr_try_cast<S>(input: &mut S) -> ModalResult<Expr>
93where
94 S: TokenStream,
95{
96 let parse = cut_err(seq! {Expr::TryCast {
97 _: Token::LParen,
98 expr: expr_parse.map(Box::new),
99 _: Keyword::AS,
100 data_type: data_type,
101 _: Token::RParen,
102 }});
103
104 trace("expr_try_cast", parse).parse_next(input)
105}
106
107pub fn expr_extract<S>(input: &mut S) -> ModalResult<Expr>
109where
110 S: TokenStream,
111{
112 let mut date_time_field = token
113 .verify_map(|token| match token.token {
114 Token::Word(w) => Some(w.value.to_uppercase()),
115 Token::SingleQuotedString(s) => Some(s.to_uppercase()),
116 _ => None,
117 })
118 .expect("date/time field");
119
120 let parse = cut_err(seq! {Expr::Extract {
121 _: Token::LParen,
122 field: date_time_field,
123 _: Keyword::FROM,
124 expr: expr_parse.map(Box::new),
125 _: Token::RParen,
126 }});
127
128 trace("expr_extract", parse).parse_next(input)
129}
130
131pub fn expr_substring<S>(input: &mut S) -> ModalResult<Expr>
133where
134 S: TokenStream,
135{
136 let mut substring_from = opt(preceded(
137 alt((Token::Comma.void(), Keyword::FROM.void())),
138 cut_err(expr_parse).map(Box::new),
139 ));
140 let mut substring_for = opt(preceded(
141 alt((Token::Comma.void(), Keyword::FOR.void())),
142 cut_err(expr_parse).map(Box::new),
143 ));
144 let parse = cut_err(seq! {Expr::Substring {
145 _: Token::LParen,
146 expr: expr_parse.map(Box::new),
147 substring_from: substring_from,
148 substring_for: substring_for,
149 _: Token::RParen,
150 }});
151
152 trace("expr_substring", parse).parse_next(input)
153}
154
155pub fn expr_position<S>(input: &mut S) -> ModalResult<Expr>
157where
158 S: TokenStream,
159{
160 let parse = cut_err(seq! {Expr::Position {
161 _: Token::LParen,
162 substring: subexpr(Precedence::Between).map(Box::new),
166 _: Keyword::IN,
167 string: subexpr(Precedence::Between).map(Box::new),
168 _: Token::RParen,
169 }});
170
171 trace("expr_position", parse).parse_next(input)
172}
173
174pub fn expr_overlay<S>(input: &mut S) -> ModalResult<Expr>
176where
177 S: TokenStream,
178{
179 let mut count_parse = opt(preceded(
180 Keyword::FOR.void(),
181 cut_err(expr_parse).map(Box::new),
182 ));
183
184 let parse = cut_err(seq! {Expr::Overlay {
185 _: Token::LParen,
186 expr: expr_parse.map(Box::new),
187 _: Keyword::PLACING,
188 new_substring: expr_parse.map(Box::new),
189 _: Keyword::FROM,
190 start: expr_parse.map(Box::new),
191 count: count_parse,
192 _: Token::RParen,
193 }});
194
195 trace("expr_overlay", parse).parse_next(input)
196}