1use std::mem::discriminant;
2
3use crate::errors::{Result, VecDbError};
4
5use super::ast::{
6 Condition, Literal, Operator, OrderBy, ScalarCondition, SelectStatement, VectorCondition,
7};
8use super::lexer::{Lexer, Token};
9
10pub struct SqlParser {
15 tokens: Vec<Token>,
16 pos: usize,
17}
18
19impl SqlParser {
20 pub fn parse(sql: &str) -> Result<SelectStatement> {
22 let mut lexer = Lexer::new(sql);
23 let tokens = lexer.tokenize()?;
24 let mut parser = SqlParser { tokens, pos: 0 };
25 parser.parse_select()
26 }
27
28 fn peek(&self) -> Token {
32 self.tokens.get(self.pos).cloned().unwrap_or(Token::Eof)
33 }
34
35 fn advance(&mut self) -> Token {
37 if self.pos < self.tokens.len() {
38 let tok = self.tokens[self.pos].clone();
39 self.pos += 1;
40 tok
41 } else {
42 Token::Eof
43 }
44 }
45
46 fn expect(&mut self, expected: Token) -> Result<()> {
51 let tok = self.advance();
52 if discriminant(&tok) == discriminant(&expected) {
53 Ok(())
54 } else {
55 Err(VecDbError::InvalidQuery(format!(
56 "expected {:?}, got {:?}",
57 expected, tok
58 )))
59 }
60 }
61
62 fn is_next(&self, expected: &Token) -> bool {
64 discriminant(&self.peek()) == discriminant(expected)
65 }
66
67 fn parse_select(&mut self) -> Result<SelectStatement> {
70 self.expect(Token::Select)?;
71 let columns = self.parse_columns()?;
72 self.expect(Token::From)?;
73
74 let table = match self.advance() {
75 Token::Identifier(s) => s,
76 tok => {
77 return Err(VecDbError::InvalidQuery(format!(
78 "expected table name, got {:?}",
79 tok
80 )))
81 }
82 };
83
84 let where_clause = if self.is_next(&Token::Where) {
85 self.advance(); Some(self.parse_where_clause()?)
87 } else {
88 None
89 };
90
91 let order_by = if self.is_next(&Token::Order) {
92 self.advance(); self.expect(Token::By)?;
94 Some(self.parse_order_by()?)
95 } else {
96 None
97 };
98
99 let limit = if self.is_next(&Token::Limit) {
100 self.advance(); match self.advance() {
102 Token::IntLit(n) => Some(n as usize),
103 tok => {
104 return Err(VecDbError::InvalidQuery(format!(
105 "expected integer after LIMIT, got {:?}",
106 tok
107 )))
108 }
109 }
110 } else {
111 None
112 };
113
114 if self.is_next(&Token::Semicolon) {
116 self.advance();
117 }
118
119 Ok(SelectStatement {
120 table,
121 columns,
122 where_clause,
123 order_by,
124 limit,
125 })
126 }
127
128 fn parse_columns(&mut self) -> Result<Vec<String>> {
129 if self.is_next(&Token::Star) {
130 self.advance();
131 return Ok(vec![]);
132 }
133
134 let mut cols = Vec::new();
135 loop {
136 match self.peek() {
137 Token::Star => {
138 self.advance();
139 return Ok(vec![]);
140 }
141 Token::Identifier(_) => {
142 if let Token::Identifier(s) = self.advance() {
143 cols.push(s);
144 }
145 }
146 tok => {
147 return Err(VecDbError::InvalidQuery(format!(
148 "expected column name or '*', got {:?}",
149 tok
150 )))
151 }
152 }
153 if self.is_next(&Token::Comma) {
154 self.advance();
155 } else {
156 break;
157 }
158 }
159 Ok(cols)
160 }
161
162 fn parse_where_clause(&mut self) -> Result<Condition> {
163 self.parse_or_condition()
164 }
165
166 fn parse_or_condition(&mut self) -> Result<Condition> {
167 let mut left = self.parse_and_condition()?;
168 while self.is_next(&Token::Or) {
169 self.advance(); let right = self.parse_and_condition()?;
171 left = Condition::Or(Box::new(left), Box::new(right));
172 }
173 Ok(left)
174 }
175
176 fn parse_and_condition(&mut self) -> Result<Condition> {
177 let mut left = self.parse_atom_condition()?;
178 while self.is_next(&Token::And) {
179 self.advance(); let right = self.parse_atom_condition()?;
181 left = Condition::And(Box::new(left), Box::new(right));
182 }
183 Ok(left)
184 }
185
186 fn parse_atom_condition(&mut self) -> Result<Condition> {
187 if self.is_next(&Token::Not) {
189 self.advance();
190 let inner = self.parse_atom_condition()?;
191 return Ok(Condition::Not(Box::new(inner)));
192 }
193
194 if self.is_next(&Token::LParen) {
196 self.advance(); let cond = self.parse_or_condition()?;
198 self.expect(Token::RParen)?;
199 return Ok(cond);
200 }
201
202 if self.is_next(&Token::VectorSim) {
204 let vc = self.parse_vector_condition()?;
205 return Ok(Condition::Vector(vc));
206 }
207
208 let sc = self.parse_scalar_condition()?;
210 Ok(Condition::Scalar(sc))
211 }
212
213 fn parse_vector_condition(&mut self) -> Result<VectorCondition> {
214 self.expect(Token::VectorSim)?;
215 self.expect(Token::LParen)?;
216
217 let column = match self.advance() {
218 Token::Identifier(s) => s,
219 tok => {
220 return Err(VecDbError::InvalidQuery(format!(
221 "expected column name in VECTOR_SIM, got {:?}",
222 tok
223 )))
224 }
225 };
226
227 self.expect(Token::Comma)?;
228
229 let vector = match self.advance() {
230 Token::VectorLit(v) => v,
231 tok => {
232 return Err(VecDbError::InvalidQuery(format!(
233 "expected vector literal in VECTOR_SIM, got {:?}",
234 tok
235 )))
236 }
237 };
238
239 self.expect(Token::RParen)?;
240
241 let op = self.parse_operator()?;
242
243 let threshold = match self.advance() {
244 Token::FloatLit(f) => f as f32,
245 Token::IntLit(i) => i as f32,
246 tok => {
247 return Err(VecDbError::InvalidQuery(format!(
248 "expected similarity threshold, got {:?}",
249 tok
250 )))
251 }
252 };
253
254 Ok(VectorCondition {
255 column,
256 vector,
257 op,
258 threshold,
259 })
260 }
261
262 fn parse_scalar_condition(&mut self) -> Result<ScalarCondition> {
263 let field = self.parse_field_path()?;
264 let op = self.parse_operator()?;
265 let value = self.parse_literal()?;
266 Ok(ScalarCondition { field, op, value })
267 }
268
269 fn parse_field_path(&mut self) -> Result<String> {
277 let mut path = match self.advance() {
278 Token::Identifier(s) => s,
279 tok => {
280 return Err(VecDbError::InvalidQuery(format!(
281 "expected field name, got {:?}",
282 tok
283 )))
284 }
285 };
286
287 loop {
288 match self.peek() {
289 Token::Dot => {
290 self.advance();
291 match self.advance() {
292 Token::Identifier(s) => path = format!("{path}.{s}"),
293 tok => {
294 return Err(VecDbError::InvalidQuery(format!(
295 "expected field after '.', got {:?}",
296 tok
297 )))
298 }
299 }
300 }
301 Token::Arrow => {
302 self.advance();
303 match self.advance() {
304 Token::StringLit(s) => path = format!("{path}->'{s}'"),
305 Token::Identifier(s) => path = format!("{path}->{s}"),
306 tok => {
307 return Err(VecDbError::InvalidQuery(format!(
308 "expected key after '->', got {:?}",
309 tok
310 )))
311 }
312 }
313 }
314 Token::ArrowText => {
315 self.advance();
316 match self.advance() {
317 Token::StringLit(s) => path = format!("{path}->>'{}'", s),
318 Token::Identifier(s) => path = format!("{path}->>{s}"),
319 tok => {
320 return Err(VecDbError::InvalidQuery(format!(
321 "expected key after '->>', got {:?}",
322 tok
323 )))
324 }
325 }
326 }
327 _ => break,
328 }
329 }
330 Ok(path)
331 }
332
333 fn parse_operator(&mut self) -> Result<Operator> {
334 match self.advance() {
335 Token::Eq => Ok(Operator::Eq),
336 Token::NotEq => Ok(Operator::NotEq),
337 Token::Lt => Ok(Operator::Lt),
338 Token::LtEq => Ok(Operator::LtEq),
339 Token::Gt => Ok(Operator::Gt),
340 Token::GtEq => Ok(Operator::GtEq),
341 Token::Like => Ok(Operator::Like),
342 tok => Err(VecDbError::InvalidQuery(format!(
343 "expected comparison operator, got {:?}",
344 tok
345 ))),
346 }
347 }
348
349 fn parse_literal(&mut self) -> Result<Literal> {
350 match self.advance() {
351 Token::StringLit(s) => Ok(Literal::String(s)),
352 Token::FloatLit(f) => Ok(Literal::Float(f)),
353 Token::IntLit(i) => Ok(Literal::Integer(i)),
354 Token::True => Ok(Literal::Bool(true)),
355 Token::False => Ok(Literal::Bool(false)),
356 tok => Err(VecDbError::InvalidQuery(format!(
357 "expected literal value, got {:?}",
358 tok
359 ))),
360 }
361 }
362
363 fn parse_order_by(&mut self) -> Result<OrderBy> {
364 let field = match self.advance() {
365 Token::Identifier(s) => s,
366 tok => {
367 return Err(VecDbError::InvalidQuery(format!(
368 "expected field for ORDER BY, got {:?}",
369 tok
370 )))
371 }
372 };
373 let descending = if self.is_next(&Token::Desc) {
374 self.advance();
375 true
376 } else if self.is_next(&Token::Asc) {
377 self.advance();
378 false
379 } else {
380 false };
382 Ok(OrderBy { field, descending })
383 }
384}