1use collect_mac::collect;
2use indexmap::IndexMap as Map;
3
4use nom::branch::alt;
5use nom::bytes::complete::{tag, tag_no_case};
6use nom::character::complete::alphanumeric1;
7use nom::character::complete::char;
8use nom::character::complete::multispace0;
9use nom::combinator::map;
10use nom::combinator::opt;
11use nom::multi::separated_list1;
12use nom::sequence::delimited;
13use nom::sequence::preceded;
14use nom::sequence::tuple;
15use nom::IResult;
16
17pub use crate::parser;
18pub use crate::parser::elements;
19pub use crate::parser::elements::string_allowed_in_field;
20pub use crate::parser::whitespace;
21use crate::pqlir_parser;
22pub use crate::sql::clause;
23use crate::sql::Expr;
24use crate::sql::Field;
25use crate::sql::Selector;
26use crate::sql::SelectorNode;
27use crate::value::PqlValue;
28
29pub fn pqlvalue_as_field(input: &str) -> IResult<&str, Field> {
30 let (input, (value, alias)) = tuple((
31 pqlir_parser::root,
32 opt(preceded(
33 opt(preceded(multispace0, tag_no_case("AS"))),
34 preceded(multispace0, alphanumeric1),
35 )),
36 ))(input)?;
37
38 let field = Field {
39 expr: Expr::Value(value),
40 alias: alias.map(String::from),
41 };
42 Ok((input, field))
43}
44
45pub fn parse_field(input: &str) -> IResult<&str, Field> {
46 alt((expr_as_field, pqlvalue_as_field, selector_as_field))(input)
47}
48
49pub fn pqlvalue_with_alias_to_pql_value(input: &str) -> IResult<&str, PqlValue> {
61 let (input, field) = pqlvalue_as_field(input)?;
62 let value = match field {
63 Field {
64 expr: Expr::Value(value),
65 alias: Some(alias),
66 } => PqlValue::Object(collect! {
67 as Map::<String , PqlValue>:
68 alias.to_string() => value
69 }),
70 _ => todo!(),
71 };
72 Ok((input, value))
73}
74
75pub fn selector_as_field(input: &str) -> IResult<&str, Field> {
76 let (input, (selector, alias)) = tuple((
77 parse_selector,
78 opt(preceded(
79 opt(preceded(multispace0, tag_no_case("AS"))),
80 preceded(multispace0, alphanumeric1),
81 )),
82 ))(input)?;
83
84 let field = Field {
85 expr: Expr::Selector(selector),
86 alias: alias.map(String::from),
87 };
88 Ok((input, field))
89}
90
91pub fn projection(input: &str) -> IResult<&str, (Selector, Option<String>)> {
92 let (input, (selector, opt_alias)) = tuple((
93 parse_selector,
94 opt(preceded(
95 opt(preceded(multispace0, tag_no_case("AS"))),
96 preceded(multispace0, alphanumeric1),
97 )),
98 ))(input)?;
99 Ok((input, (selector, opt_alias.map(String::from))))
100}
101
102pub fn expr_as_field(input: &str) -> IResult<&str, Field> {
103 let (input, (expr, alias)) = tuple((
105 alt((
106 parse_star_as_expr,
107 parser::math::parse,
108 parser::elements::float_number,
109 parser::func::count,
110 )),
111 opt(preceded(
112 opt(preceded(multispace0, tag_no_case("AS"))),
113 preceded(multispace0, alphanumeric1),
114 )),
115 ))(input)?;
116
117 let field = Field {
118 expr,
119 alias: alias.map(String::from),
120 };
121 Ok((input, field))
122}
123
124pub fn parse_expr(input: &str) -> IResult<&str, Expr> {
125 alt((
127 parse_star_as_expr,
128 parser::math::parse,
129 parser::elements::float_number,
130 parser::func::count,
131 ))(input)
132}
133
134pub fn parse_star_as_expr(input: &str) -> IResult<&str, Expr> {
135 map(tag("*"), |_| Expr::Star)(input)
136}
137
138pub fn parse_sql_as_expr(_input: &str) -> IResult<&str, Expr> {
139 todo!()
140 }
142
143pub fn parse_alias_in_from_clause(input: &str) -> IResult<&str, String> {
144 let (input, (_, alias)) = tuple((
145 opt(preceded(whitespace, tag_no_case("AS"))),
146 preceded(whitespace, string_allowed_in_field),
147 ))(input)?;
148 Ok((input, alias))
149}
150
151pub fn parse_selector(input: &str) -> IResult<&str, Selector> {
152 pub fn selecotrnode_with_index<'a>(input: &str) -> IResult<&str, Vec<SelectorNode>> {
153 let (input, (s, opt_i)) = tuple((
154 string_allowed_in_field,
155 opt(delimited(char('['), elements::integer, char(']'))),
156 ))(input)?;
157
158 let mut nodes = vec![];
159 nodes.push(SelectorNode::String(s));
160 if let Some(i) = opt_i {
161 nodes.push(SelectorNode::Number(i as i64));
162 };
163
164 Ok((input, nodes))
165 }
166
167 let (input, (opt_dot, vec_nodes)) = tuple((
168 opt(char('.')),
169 separated_list1(char('.'), selecotrnode_with_index),
170 ))(input)?;
171
172 let mut nodes = vec![];
173 if let Some(_dot) = opt_dot {
174 nodes.push(SelectorNode::default())
175 }
176 let mut nodes2 = vec_nodes.into_iter().flatten().collect::<Vec<_>>();
177 nodes.append(&mut nodes2);
178 let res = Selector::from(nodes.as_slice());
179 Ok((input, res))
180}
181
182pub fn parse_path_as_expr<'a>(input: &'a str) -> IResult<&'a str, Expr> {
183 map(parse_selector, |selector| Expr::Selector(selector))(input)
184}
185
186#[cfg(test)]
187mod tests {
188 use super::parse_selector;
189 use crate::parser;
190 use crate::sql::Selector;
191 use crate::sql::SelectorNode;
192 use crate::value::PqlValue;
193 use std::str::FromStr;
194
195 #[test]
196 fn selector_xyz() -> anyhow::Result<()> {
197 let (_, selector) = parse_selector("x.y.z")?;
198
199 let expected = Selector::from(
200 vec![
201 SelectorNode::from("x"),
202 SelectorNode::from("y"),
203 SelectorNode::from("z"),
204 ]
205 .as_slice(),
206 );
207
208 assert_eq!(selector, expected);
209 Ok(())
210 }
211
212 #[test]
213 fn selector_xy2z() -> anyhow::Result<()> {
214 let (_, selector) = parse_selector("x.y[2].z")?;
215
216 let expected = Selector::from(
217 vec![
218 SelectorNode::from("x"),
219 SelectorNode::from("y"),
220 SelectorNode::from(2),
221 SelectorNode::from("z"),
222 ]
223 .as_slice(),
224 );
225
226 assert_eq!(selector, expected);
227 Ok(())
228 }
229
230 #[test]
231 fn alias_pql_vlaue_to_pql_value() -> anyhow::Result<()> {
232 let value = parser::expressions::pqlvalue_with_alias_to_pql_value(r#"[1,2,3] AS arr"#)?.1;
233 let expected = PqlValue::from_str(r#"{ "arr" : [1,2,3] }"#)?;
234 assert_eq!(value, expected);
235 Ok(())
236 }
237}