Skip to main content

partiql/parser/
select_statement.rs

1use nom::character::complete::multispace0;
2use nom::{
3    branch::alt,
4    combinator::opt,
5    sequence::{preceded, tuple},
6    IResult,
7};
8
9use crate::parser::clauses;
10
11use crate::sql::Sql;
12
13pub fn from_str(input: &str) -> anyhow::Result<Sql> {
14    match parse_planner_sql(input) {
15        Ok((_, sql)) => Ok(sql),
16        Err(nom::Err::Incomplete(_needed)) => {
17            anyhow::bail!("needed")
18        }
19        Err(nom::Err::Error(err)) => {
20            dbg!(&err);
21            eprintln!("{}", err);
22            anyhow::bail!("parser error")
23        }
24        Err(nom::Err::Failure(err)) => {
25            dbg!(&err);
26            eprintln!("{}", err);
27            anyhow::bail!("parse failed")
28        }
29    }
30}
31
32pub fn parse_planner_sql(input: &str) -> IResult<&str, Sql> {
33    alt((parse_sql21, parse_sql22))(input)
34}
35
36pub fn parse_sql21(input: &str) -> IResult<&str, Sql> {
37    let (
38        input,
39        (
40            opt_select_clause,
41            opt_from_clause,
42            opt_left_join_clause,
43            opt_where_clause,
44            opt_order_by,
45            opt_limit,
46        ),
47    ) = tuple((
48        opt(preceded(multispace0, clauses::select)),
49        opt(preceded(multispace0, clauses::from)),
50        opt(preceded(multispace0, clauses::left_join)),
51        opt(preceded(multispace0, clauses::parse_where)),
52        opt(preceded(multispace0, clauses::orderby)),
53        opt(preceded(multispace0, clauses::limit)),
54    ))(input)?;
55
56    let sql = Sql {
57        select_clause: opt_select_clause.unwrap_or_default(),
58        from_clause: opt_from_clause.unwrap_or_default(),
59        left_join_clause: opt_left_join_clause.unwrap_or_default(),
60        where_clause: opt_where_clause.map(Box::new),
61        orderby: opt_order_by,
62        limit: opt_limit,
63    };
64    Ok((input, sql))
65}
66
67pub fn parse_sql22(input: &str) -> IResult<&str, Sql> {
68    let (
69        input,
70        (
71            opt_from_clause,
72            opt_left_join_clause,
73            opt_where_clause,
74            opt_select_clause,
75            opt_order_by,
76            opt_limit,
77        ),
78    ) = tuple((
79        opt(preceded(multispace0, clauses::from)),
80        opt(preceded(multispace0, clauses::left_join)),
81        opt(preceded(multispace0, clauses::parse_where)),
82        opt(preceded(multispace0, clauses::select)),
83        opt(preceded(multispace0, clauses::orderby)),
84        opt(preceded(multispace0, clauses::limit)),
85    ))(input)?;
86
87    let sql = Sql {
88        select_clause: opt_select_clause.unwrap_or_default(),
89        from_clause: opt_from_clause.unwrap_or_default(),
90        left_join_clause: opt_left_join_clause.unwrap_or_default(),
91        where_clause: opt_where_clause.map(Box::new),
92        orderby: opt_order_by,
93        limit: opt_limit,
94    };
95    Ok((input, sql))
96}