sqlparser_mysql/base/
order.rs1use std::fmt;
2use std::fmt::{Display, Formatter};
3use std::str;
4
5use nom::branch::alt;
6use nom::bytes::complete::tag_no_case;
7use nom::character::complete::{multispace0, multispace1};
8use nom::combinator::{map, opt};
9use nom::multi::many0;
10use nom::sequence::{preceded, tuple};
11use nom::IResult;
12
13use base::column::Column;
14use base::error::ParseSQLError;
15use base::{CommonParser, DisplayUtil};
16
17#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
18pub struct OrderClause {
19 pub columns: Vec<(Column, OrderType)>, }
21
22impl OrderClause {
23 pub fn parse(i: &str) -> IResult<&str, OrderClause, ParseSQLError<&str>> {
25 let (remaining_input, (_, _, _, _, _, columns)) = tuple((
26 multispace0,
27 tag_no_case("ORDER"),
28 multispace1,
29 tag_no_case("BY"),
30 multispace1,
31 many0(Self::order_expr),
32 ))(i)?;
33
34 Ok((remaining_input, OrderClause { columns }))
35 }
36
37 fn order_expr(i: &str) -> IResult<&str, (Column, OrderType), ParseSQLError<&str>> {
38 let (remaining_input, (field_name, ordering, _)) = tuple((
39 Column::without_alias,
40 opt(preceded(multispace0, OrderType::parse)),
41 opt(CommonParser::ws_sep_comma),
42 ))(i)?;
43
44 Ok((
45 remaining_input,
46 (field_name, ordering.unwrap_or(OrderType::Asc)),
47 ))
48 }
49}
50
51impl fmt::Display for OrderClause {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 write!(f, "ORDER BY ")?;
54 write!(
55 f,
56 "{}",
57 self.columns
58 .iter()
59 .map(|(c, o)| format!("{} {}", DisplayUtil::escape_if_keyword(&c.name), o))
60 .collect::<Vec<_>>()
61 .join(", ")
62 )
63 }
64}
65
66#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
68pub enum OrderType {
69 Asc,
70 Desc,
71}
72
73impl OrderType {
74 pub fn parse(i: &str) -> IResult<&str, OrderType, ParseSQLError<&str>> {
75 alt((
76 map(tag_no_case("DESC"), |_| OrderType::Desc),
77 map(tag_no_case("ASC"), |_| OrderType::Asc),
78 ))(i)
79 }
80}
81
82impl Display for OrderType {
83 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
84 match *self {
85 OrderType::Asc => write!(f, "ASC"),
86 OrderType::Desc => write!(f, "DESC"),
87 }
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn parse_order_clause() {
97 let str1 = "order by name desc";
98 let str2 = "order by name asc, age desc";
99 let str3 = "order by name";
100
101 let expected_ord1 = OrderClause {
102 columns: vec![("name".into(), OrderType::Desc)],
103 };
104 let expected_ord2 = OrderClause {
105 columns: vec![
106 ("name".into(), OrderType::Asc),
107 ("age".into(), OrderType::Desc),
108 ],
109 };
110 let expected_ord3 = OrderClause {
111 columns: vec![("name".into(), OrderType::Asc)],
112 };
113
114 let res1 = OrderClause::parse(str1);
115 let res2 = OrderClause::parse(str2);
116 let res3 = OrderClause::parse(str3);
117 assert_eq!(res1.unwrap().1, expected_ord1);
118 assert_eq!(res2.unwrap().1, expected_ord2);
119 assert_eq!(res3.unwrap().1, expected_ord3);
120 }
121
122 #[test]
123 fn parse_order_type() {
124 let str1 = "aSc";
125 let res1 = OrderType::parse(str1);
126 assert!(res1.is_ok());
127 assert_eq!(res1.unwrap().1, OrderType::Asc);
128
129 let str2 = "desc";
130 let res2 = OrderType::parse(str2);
131 assert!(res2.is_ok());
132 assert_eq!(res2.unwrap().1, OrderType::Desc);
133 }
134}