qail_core/parser/grammar/
case_when.rs1use super::base::{parse_operator, parse_value};
4use super::expressions::{parse_expression, parse_multiplicative_expr};
5use crate::ast::*;
6use nom::{
7 IResult, Parser,
8 bytes::complete::tag_no_case,
9 character::complete::{multispace0, multispace1},
10 combinator::opt,
11 multi::separated_list0,
12 sequence::preceded,
13};
14
15pub fn parse_case(input: &str) -> IResult<&str, Expr> {
17 let (input, _) = tag_no_case("case").parse(input)?;
18 let (input, _) = multispace1(input)?;
19
20 let (input, when_clauses) = separated_list0(multispace1, parse_when).parse(input)?;
21 if when_clauses.is_empty() {
22 return Err(nom::Err::Error(nom::error::Error::new(
23 input,
24 nom::error::ErrorKind::Verify,
25 )));
26 }
27
28 let (input, _) = multispace0(input)?;
29
30 let (input, else_value) = opt(preceded(
32 (tag_no_case("else"), multispace1),
33 parse_expression,
34 ))
35 .parse(input)?;
36
37 let (input, _) = multispace0(input)?;
38 let (input, _) = tag_no_case("end").parse(input)?;
39
40 Ok((
41 input,
42 Expr::Case {
43 when_clauses,
44 else_value: else_value.map(Box::new),
45 alias: None,
46 },
47 ))
48}
49
50pub fn parse_when(input: &str) -> IResult<&str, (Condition, Box<Expr>)> {
52 let (input, _) = tag_no_case("when").parse(input)?;
53 let (input, _) = multispace1(input)?;
54
55 let (input, left_expr) = parse_multiplicative_expr(input)?; let (input, _) = multispace0(input)?;
57
58 let (input, op) = parse_operator(input)?;
60 let (input, _) = multispace0(input)?;
61
62 let (input, val) = if matches!(op, Operator::IsNull | Operator::IsNotNull) {
64 (input, Value::Null)
65 } else {
66 parse_value(input)?
67 };
68
69 let (input, _) = multispace0(input)?;
71 let (input, _) = tag_no_case("then").parse(input)?;
72 let (input, _) = multispace1(input)?;
73
74 let (input, then_expr) = parse_expression(input)?;
75
76 Ok((
77 input,
78 (
79 Condition {
80 left: left_expr,
81 op,
82 value: val,
83 is_array_unnest: false,
84 },
85 Box::new(then_expr),
86 ),
87 ))
88}