Skip to main content

surql_parser/upstream/syn/parser/stmt/
select.rs

1use super::parts::MissingKind;
2use crate::upstream::sql::order::{OrderList, Ordering};
3use crate::upstream::sql::statements::SelectStatement;
4use crate::upstream::sql::{Expr, Fields, Limit, Literal, Order, Split, Splits, Start};
5use crate::upstream::syn::parser::mac::expected;
6use crate::upstream::syn::parser::{ParseResult, Parser};
7use crate::upstream::syn::token::{Span, t};
8use reblessive::Stk;
9impl Parser<'_> {
10	/// expects `select` to be eaten.
11	pub async fn parse_select_stmt(&mut self, stk: &mut Stk) -> ParseResult<SelectStatement> {
12		let before = self.peek().span;
13		let fields = self.parse_fields(stk).await?;
14		let fields_span = before.covers(self.last_span());
15		let omit = if self.eat(t!("OMIT")) {
16			let mut fields = Vec::new();
17			loop {
18				let expr = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
19				fields.push(expr);
20				if !self.eat(t!(",")) {
21					break;
22				}
23			}
24			fields
25		} else {
26			vec![]
27		};
28		expected!(self, t!("FROM"));
29		let only = self.eat(t!("ONLY"));
30		let mut what = vec![stk.run(|ctx| self.parse_expr_table(ctx)).await?];
31		while self.eat(t!(",")) {
32			what.push(stk.run(|ctx| self.parse_expr_table(ctx)).await?);
33		}
34		let with = self.try_parse_with()?;
35		let cond = self.try_parse_condition(stk).await?;
36		let split_before = self.peek().span;
37		let split = self.try_parse_split(&fields, fields_span)?;
38		let split_span = split
39			.as_ref()
40			.map(|_| split_before.covers(self.last_span()));
41		let group = self.try_parse_group(&fields, fields_span, split_span)?;
42		let order = self.try_parse_orders(&fields, fields_span)?;
43		let (limit, start) = if let t!("START") = self.peek_kind() {
44			let start = self.try_parse_start(stk).await?;
45			let limit = self.try_parse_limit(stk).await?;
46			(limit, start)
47		} else {
48			let limit = self.try_parse_limit(stk).await?;
49			let start = self.try_parse_start(stk).await?;
50			(limit, start)
51		};
52		let fetch = self.try_parse_fetch(stk).await?;
53		let version = if self.eat(t!("VERSION")) {
54			stk.run(|stk| self.parse_expr_field(stk)).await?
55		} else {
56			Expr::Literal(Literal::None)
57		};
58		let timeout = self.try_parse_timeout(stk).await?;
59		let tempfiles = self.eat(t!("TEMPFILES"));
60		let explain = self.try_parse_explain()?;
61		Ok(SelectStatement {
62			fields,
63			omit,
64			only,
65			what,
66			with,
67			cond,
68			split,
69			group,
70			order,
71			limit,
72			start,
73			fetch,
74			version,
75			timeout,
76			tempfiles,
77			explain,
78		})
79	}
80	pub fn try_parse_split(
81		&mut self,
82		fields: &Fields,
83		fields_span: Span,
84	) -> ParseResult<Option<Splits>> {
85		if !self.eat(t!("SPLIT")) {
86			return Ok(None);
87		}
88		self.eat(t!("ON"));
89		let has_all = fields.contains_all();
90		let before = self.peek().span;
91		let split = self.parse_basic_idiom()?;
92		let split_span = before.covers(self.last_span());
93		if !has_all {
94			Self::check_idiom(MissingKind::Split, fields, fields_span, &split, split_span)?;
95		}
96		let mut res = vec![Split(split)];
97		while self.eat(t!(",")) {
98			let before = self.peek().span;
99			let split = self.parse_basic_idiom()?;
100			let split_span = before.covers(self.last_span());
101			if !has_all {
102				Self::check_idiom(MissingKind::Split, fields, fields_span, &split, split_span)?;
103			}
104			res.push(Split(split))
105		}
106		Ok(Some(Splits(res)))
107	}
108	pub fn try_parse_orders(
109		&mut self,
110		fields: &Fields,
111		fields_span: Span,
112	) -> ParseResult<Option<Ordering>> {
113		if !self.eat(t!("ORDER")) {
114			return Ok(None);
115		}
116		self.eat(t!("BY"));
117		if let t!("RAND") = self.peek_kind() {
118			self.pop_peek();
119			let start = expected!(self, t!("(")).span;
120			self.expect_closing_delimiter(t!(")"), start)?;
121			return Ok(Some(Ordering::Random));
122		}
123		let has_all = fields.contains_all();
124		let before = self.recent_span();
125		let order = self.parse_order()?;
126		let order_span = before.covers(self.last_span());
127		if !has_all {
128			Self::check_idiom(
129				MissingKind::Order,
130				fields,
131				fields_span,
132				&order.value,
133				order_span,
134			)?;
135		}
136		let mut orders = vec![order];
137		while self.eat(t!(",")) {
138			let before = self.recent_span();
139			let order = self.parse_order()?;
140			let order_span = before.covers(self.last_span());
141			if !has_all {
142				Self::check_idiom(
143					MissingKind::Order,
144					fields,
145					fields_span,
146					&order.value,
147					order_span,
148				)?;
149			}
150			orders.push(order)
151		}
152		Ok(Some(Ordering::Order(OrderList(orders))))
153	}
154	fn parse_order(&mut self) -> ParseResult<Order> {
155		let start = self.parse_basic_idiom()?;
156		let collate = self.eat(t!("COLLATE"));
157		let numeric = self.eat(t!("NUMERIC"));
158		let direction = match self.peek_kind() {
159			t!("ASCENDING") => {
160				self.pop_peek();
161				true
162			}
163			t!("DESCENDING") => {
164				self.pop_peek();
165				false
166			}
167			_ => true,
168		};
169		Ok(Order {
170			value: start,
171			collate,
172			numeric,
173			direction,
174		})
175	}
176	pub async fn try_parse_limit(&mut self, stk: &mut Stk) -> ParseResult<Option<Limit>> {
177		if !self.eat(t!("LIMIT")) {
178			return Ok(None);
179		}
180		self.eat(t!("BY"));
181		let value = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
182		Ok(Some(Limit(value)))
183	}
184	pub async fn try_parse_start(&mut self, stk: &mut Stk) -> ParseResult<Option<Start>> {
185		if !self.eat(t!("START")) {
186			return Ok(None);
187		}
188		self.eat(t!("AT"));
189		let value = stk.run(|ctx| self.parse_expr_field(ctx)).await?;
190		Ok(Some(Start(value)))
191	}
192}