1use crate::ast::span::Spanned;
2use crate::ast::{Assignment, Delete, Insert, OrderByExpr, Select, SelectItem, TableRef, Update};
3use crate::error::Result;
4use crate::tokenizer::keyword::Keyword;
5use crate::tokenizer::token::{Token, Word};
6
7use super::Parser;
8
9impl<'a> Parser<'a> {
10 pub fn parse_select(&mut self) -> Result<Select> {
11 let start_span = self.expect_keyword("SELECT", Keyword::SELECT)?;
12 let distinct = self.consume_keyword(Keyword::DISTINCT);
13
14 let projection = self.parse_projection_list()?;
15
16 self.expect_keyword("FROM", Keyword::FROM)?;
17 let from = self.parse_table_ref()?;
18 let mut end_span = from.span;
19
20 let selection = if self.consume_keyword(Keyword::WHERE) {
21 let expr = self.parse_expr()?;
22 end_span = end_span.union(&expr.span());
23 Some(expr)
24 } else {
25 None
26 };
27
28 let order_by = if self.consume_keyword(Keyword::ORDER) {
29 self.expect_keyword("BY", Keyword::BY)?;
30 let items = self.parse_order_by()?;
31 if let Some(last) = items.last() {
32 end_span = end_span.union(&last.span);
33 }
34 items
35 } else {
36 Vec::new()
37 };
38
39 let mut limit = None;
40 let mut offset = None;
41 if self.consume_keyword(Keyword::LIMIT) {
42 let lim = self.parse_expr()?;
43 end_span = end_span.union(&lim.span());
44 limit = Some(lim);
45
46 if self.consume_keyword(Keyword::OFFSET) {
47 let off = self.parse_expr()?;
48 end_span = end_span.union(&off.span());
49 offset = Some(off);
50 }
51 }
52
53 let span = start_span.union(&end_span);
54 Ok(Select {
55 distinct,
56 projection,
57 from,
58 selection,
59 order_by,
60 limit,
61 offset,
62 span,
63 })
64 }
65
66 fn parse_projection_list(&mut self) -> Result<Vec<SelectItem>> {
67 let mut items = Vec::new();
68 loop {
69 items.push(self.parse_select_item()?);
70 if matches!(self.peek().token, Token::Comma) {
71 self.advance();
72 continue;
73 }
74 break;
75 }
76 Ok(items)
77 }
78
79 fn parse_select_item(&mut self) -> Result<SelectItem> {
80 let tok = self.peek().clone();
81 if matches!(tok.token, Token::Mul) {
82 self.advance();
83 return Ok(SelectItem::Wildcard { span: tok.span });
84 }
85
86 let expr = self.parse_expr()?;
87 let mut span = expr.span();
88 let mut alias = None;
89
90 if self.consume_keyword(Keyword::AS) {
91 let (name, alias_span) = self.parse_identifier()?;
92 span = span.union(&alias_span);
93 alias = Some(name);
94 } else if let Token::Word(Word {
95 keyword: Keyword::NoKeyword,
96 ..
97 }) = &self.peek().token
98 {
99 let alias_tok = self.advance();
100 if let Token::Word(Word { value, .. }) = alias_tok.token {
101 span = span.union(&alias_tok.span);
102 alias = Some(value);
103 }
104 }
105
106 Ok(SelectItem::Expr { expr, alias, span })
107 }
108
109 fn parse_table_ref(&mut self) -> Result<TableRef> {
110 let (name, name_span) = self.parse_identifier()?;
111 let mut alias = None;
112 let mut span = name_span;
113
114 if self.consume_keyword(Keyword::AS) {
115 let (a, alias_span) = self.parse_identifier()?;
116 alias = Some(a);
117 span = span.union(&alias_span);
118 } else if let Token::Word(Word {
119 keyword: Keyword::NoKeyword,
120 ..
121 }) = &self.peek().token
122 {
123 let alias_tok = self.advance();
124 if let Token::Word(Word { value, .. }) = alias_tok.token {
125 span = span.union(&alias_tok.span);
126 alias = Some(value);
127 }
128 }
129
130 Ok(TableRef { name, alias, span })
131 }
132
133 fn parse_order_by(&mut self) -> Result<Vec<OrderByExpr>> {
134 let mut items = Vec::new();
135 loop {
136 let expr = self.parse_expr()?;
137 let mut span = expr.span();
138 let mut asc = None;
139 let mut nulls_first = None;
140
141 if let Token::Word(Word { keyword, .. }) = &self.peek().token {
142 match keyword {
143 Keyword::ASC => {
144 let s = self.advance().span;
145 span = span.union(&s);
146 asc = Some(true);
147 }
148 Keyword::DESC => {
149 let s = self.advance().span;
150 span = span.union(&s);
151 asc = Some(false);
152 }
153 _ => {}
154 }
155 }
156
157 if let Token::Word(Word {
158 keyword: Keyword::NULLS,
159 ..
160 }) = &self.peek().token
161 {
162 let nulls_tok = self.advance();
163 let dir_tok = self.expect_token("FIRST or LAST", |t| {
164 matches!(
165 t,
166 Token::Word(Word {
167 keyword: Keyword::FIRST | Keyword::LAST,
168 ..
169 })
170 )
171 })?;
172 nulls_first = Some(matches!(
173 dir_tok.token,
174 Token::Word(Word {
175 keyword: Keyword::FIRST,
176 ..
177 })
178 ));
179 span = span.union(&nulls_tok.span).union(&dir_tok.span);
180 }
181
182 items.push(OrderByExpr {
183 expr,
184 asc,
185 nulls_first,
186 span,
187 });
188
189 if matches!(self.peek().token, Token::Comma) {
190 self.advance();
191 continue;
192 }
193 break;
194 }
195
196 Ok(items)
197 }
198
199 pub fn parse_insert(&mut self) -> Result<Insert> {
200 let start_span = self.expect_keyword("INSERT", Keyword::INSERT)?;
201 self.expect_keyword("INTO", Keyword::INTO)?;
202 let (table, table_span) = self.parse_identifier()?;
203 let mut end_span = table_span;
204 let mut columns = None;
205
206 if matches!(self.peek().token, Token::LParen) {
207 self.advance();
208 let mut cols = Vec::new();
209 loop {
210 let (col, col_span) = self.parse_identifier()?;
211 end_span = end_span.union(&col_span);
212 cols.push(col);
213 if matches!(self.peek().token, Token::Comma) {
214 self.advance();
215 continue;
216 }
217 break;
218 }
219 let close = self
220 .expect_token("')'", |t| matches!(t, Token::RParen))?
221 .span;
222 end_span = end_span.union(&close);
223 columns = Some(cols);
224 }
225
226 self.expect_keyword("VALUES", Keyword::VALUES)?;
227 let mut values = Vec::new();
228 loop {
229 self.expect_token("'('", |t| matches!(t, Token::LParen))?;
230 let mut row = Vec::new();
231 row.push(self.parse_expr()?);
232 while matches!(self.peek().token, Token::Comma) {
233 self.advance();
234 row.push(self.parse_expr()?);
235 }
236 let row_end = self
237 .expect_token("')'", |t| matches!(t, Token::RParen))?
238 .span;
239 end_span = end_span.union(&row_end);
240 values.push(row);
241
242 if matches!(self.peek().token, Token::Comma) {
243 self.advance();
244 continue;
245 }
246 break;
247 }
248
249 let span = start_span.union(&end_span);
250 Ok(Insert {
251 table,
252 columns,
253 values,
254 span,
255 })
256 }
257
258 pub fn parse_update(&mut self) -> Result<Update> {
259 let start_span = self.expect_keyword("UPDATE", Keyword::UPDATE)?;
260 let (table, table_span) = self.parse_identifier()?;
261 self.expect_keyword("SET", Keyword::SET)?;
262
263 let mut assignments = Vec::new();
264 loop {
265 let (column, col_span) = self.parse_identifier()?;
266 self.expect_token("'='", |t| matches!(t, Token::Eq))?;
267 let value = self.parse_expr()?;
268 let span = col_span.union(&value.span());
269 assignments.push(Assignment {
270 column,
271 value,
272 span,
273 });
274
275 if matches!(self.peek().token, Token::Comma) {
276 self.advance();
277 continue;
278 }
279 break;
280 }
281
282 let mut end_span = assignments.last().map(|a| a.span).unwrap_or(table_span);
283
284 let selection = if self.consume_keyword(Keyword::WHERE) {
285 let expr = self.parse_expr()?;
286 end_span = end_span.union(&expr.span());
287 Some(expr)
288 } else {
289 None
290 };
291
292 let span = start_span.union(&end_span);
293 Ok(Update {
294 table,
295 assignments,
296 selection,
297 span,
298 })
299 }
300
301 pub fn parse_delete(&mut self) -> Result<Delete> {
302 let start_span = self.expect_keyword("DELETE", Keyword::DELETE)?;
303 self.expect_keyword("FROM", Keyword::FROM)?;
304 let (table, table_span) = self.parse_identifier()?;
305 let mut end_span = table_span;
306
307 let selection = if self.consume_keyword(Keyword::WHERE) {
308 let expr = self.parse_expr()?;
309 end_span = end_span.union(&expr.span());
310 Some(expr)
311 } else {
312 None
313 };
314
315 let span = start_span.union(&end_span);
316 Ok(Delete {
317 table,
318 selection,
319 span,
320 })
321 }
322}