Skip to main content

reifydb_sql/
parser.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2026 ReifyDB
3
4use crate::{
5	Error,
6	ast::*,
7	token::{Keyword, Token},
8};
9
10pub struct Parser {
11	tokens: Vec<Token>,
12	pos: usize,
13}
14
15impl Parser {
16	pub fn new(tokens: Vec<Token>) -> Self {
17		Self {
18			tokens,
19			pos: 0,
20		}
21	}
22
23	pub fn parse(&mut self) -> Result<Statement, Error> {
24		let stmt = match self.peek()? {
25			Token::Keyword(Keyword::With) => self.parse_select()?,
26			Token::Keyword(Keyword::Select) => self.parse_select()?,
27			Token::Keyword(Keyword::Insert) => self.parse_insert()?,
28			Token::Keyword(Keyword::Update) => self.parse_update()?,
29			Token::Keyword(Keyword::Delete) => self.parse_delete()?,
30			Token::Keyword(Keyword::Create) => self.parse_create()?,
31			Token::Keyword(Keyword::Drop) => self.parse_drop()?,
32			other => return Err(Error(format!("unexpected token: {other:?}"))),
33		};
34
35		if self.pos < self.tokens.len() && self.tokens[self.pos] == Token::Semicolon {
36			self.pos += 1;
37		}
38		Ok(stmt)
39	}
40
41	fn peek(&self) -> Result<&Token, Error> {
42		self.tokens.get(self.pos).ok_or_else(|| Error("unexpected end of input".into()))
43	}
44
45	fn advance(&mut self) -> Result<Token, Error> {
46		if self.pos < self.tokens.len() {
47			let tok = self.tokens[self.pos].clone();
48			self.pos += 1;
49			Ok(tok)
50		} else {
51			Err(Error("unexpected end of input".into()))
52		}
53	}
54
55	fn expect_keyword(&mut self, kw: Keyword) -> Result<(), Error> {
56		let tok = self.advance()?;
57		if tok == Token::Keyword(kw.clone()) {
58			Ok(())
59		} else {
60			Err(Error(format!("expected {kw:?}, got {tok:?}")))
61		}
62	}
63
64	fn expect_token(&mut self, expected: Token) -> Result<(), Error> {
65		let tok = self.advance()?;
66		if tok == expected {
67			Ok(())
68		} else {
69			Err(Error(format!("expected {expected:?}, got {tok:?}")))
70		}
71	}
72
73	fn at_keyword(&self, kw: &Keyword) -> bool {
74		matches!(self.tokens.get(self.pos), Some(Token::Keyword(k)) if k == kw)
75	}
76
77	fn at_token(&self, t: &Token) -> bool {
78		matches!(self.tokens.get(self.pos), Some(tok) if tok == t)
79	}
80
81	fn is_eof(&self) -> bool {
82		self.pos >= self.tokens.len()
83	}
84
85	fn expect_ident(&mut self) -> Result<String, Error> {
86		let tok = self.advance()?;
87		match tok {
88			Token::Ident(name) => Ok(name),
89
90			Token::Keyword(kw) => Ok(keyword_to_string(&kw)),
91			_ => Err(Error(format!("expected identifier, got {tok:?}"))),
92		}
93	}
94
95	fn is_ident_like(&self) -> bool {
96		match self.tokens.get(self.pos) {
97			Some(Token::Ident(_)) => true,
98			Some(Token::Keyword(kw)) => !is_structural_keyword(kw),
99			_ => false,
100		}
101	}
102
103	fn parse_select(&mut self) -> Result<Statement, Error> {
104		let sel = self.parse_select_statement()?;
105		Ok(Statement::Select(Box::new(sel)))
106	}
107
108	fn parse_select_statement(&mut self) -> Result<SelectStatement, Error> {
109		let ctes = if self.at_keyword(&Keyword::With) {
110			self.parse_cte_list()?
111		} else {
112			vec![]
113		};
114
115		self.expect_keyword(Keyword::Select)?;
116
117		let distinct = if self.at_keyword(&Keyword::Distinct) {
118			self.advance()?;
119			true
120		} else {
121			false
122		};
123
124		let columns = self.parse_select_columns()?;
125
126		let mut from = None;
127		let mut joins = Vec::new();
128
129		if self.at_keyword(&Keyword::From) {
130			self.advance()?;
131			let (first_from, _first_alias) = self.parse_from_item()?;
132			from = Some(first_from);
133
134			while self.at_token(&Token::Comma) {
135				self.advance()?;
136				let (extra_from, extra_alias) = self.parse_from_item()?;
137				let alias = extra_alias.or_else(|| match &extra_from {
138					FromClause::Table {
139						name,
140						..
141					} => Some(name.clone()),
142					_ => None,
143				});
144				joins.push(JoinClause {
145					join_type: JoinType::Cross,
146					table: extra_from,
147					table_alias: alias,
148					on: Expr::BoolLiteral(true),
149				});
150			}
151		}
152		while self.parse_join_if_present()? {
153			let join = self.finish_parse_join()?;
154			joins.push(join);
155		}
156
157		let where_clause = if self.at_keyword(&Keyword::Where) {
158			self.advance()?;
159			Some(self.parse_expr()?)
160		} else {
161			None
162		};
163
164		let group_by = if self.at_keyword(&Keyword::Group) {
165			self.advance()?;
166			self.expect_keyword(Keyword::By)?;
167			self.parse_expr_list()?
168		} else {
169			vec![]
170		};
171
172		let having = if self.at_keyword(&Keyword::Having) {
173			self.advance()?;
174			Some(self.parse_expr()?)
175		} else {
176			None
177		};
178
179		let order_by = if self.at_keyword(&Keyword::Order) {
180			self.advance()?;
181			self.expect_keyword(Keyword::By)?;
182			self.parse_order_by_list()?
183		} else {
184			vec![]
185		};
186
187		let limit = if self.at_keyword(&Keyword::Limit) {
188			self.advance()?;
189			Some(self.parse_u64()?)
190		} else {
191			None
192		};
193
194		let offset = if self.at_keyword(&Keyword::Offset) {
195			self.advance()?;
196			Some(self.parse_u64()?)
197		} else {
198			None
199		};
200
201		let set_op = if self.at_keyword(&Keyword::Union) {
202			self.advance()?;
203			let op = if self.at_keyword(&Keyword::All) {
204				self.advance()?;
205				SetOp::UnionAll
206			} else {
207				SetOp::Union
208			};
209			let right = self.parse_select_statement()?;
210			Some((op, Box::new(right)))
211		} else if self.at_keyword(&Keyword::Intersect) {
212			self.advance()?;
213			let right = self.parse_select_statement()?;
214			Some((SetOp::Intersect, Box::new(right)))
215		} else if self.at_keyword(&Keyword::Except) {
216			self.advance()?;
217			let right = self.parse_select_statement()?;
218			Some((SetOp::Except, Box::new(right)))
219		} else {
220			None
221		};
222
223		Ok(SelectStatement {
224			ctes,
225			distinct,
226			columns,
227			from,
228			joins,
229			where_clause,
230			group_by,
231			having,
232			order_by,
233			limit,
234			offset,
235			set_op,
236		})
237	}
238
239	fn parse_from_item(&mut self) -> Result<(FromClause, Option<String>), Error> {
240		let from = if self.at_token(&Token::OpenParen) {
241			self.advance()?;
242			if self.at_keyword(&Keyword::Select) {
243				let sel = self.parse_select_statement()?;
244				self.expect_token(Token::CloseParen)?;
245				FromClause::Subquery(Box::new(sel))
246			} else {
247				return Err(Error("expected subquery after '('".into()));
248			}
249		} else {
250			let name = self.expect_ident()?;
251			if self.at_token(&Token::Dot) {
252				self.advance()?;
253				let table = self.expect_ident()?;
254				FromClause::Table {
255					shape: Some(name),
256					name: table,
257					alias: None,
258				}
259			} else {
260				FromClause::Table {
261					name,
262					shape: None,
263					alias: None,
264				}
265			}
266		};
267
268		let alias = if self.at_keyword(&Keyword::As) {
269			self.advance()?;
270			Some(self.expect_ident()?)
271		} else if !self.is_eof() && self.is_ident_like() {
272			Some(self.expect_ident()?)
273		} else {
274			None
275		};
276
277		if let Some(alias) = alias {
278			match from {
279				FromClause::Table {
280					name,
281					shape,
282					..
283				} => Ok((
284					FromClause::Table {
285						name,
286						shape,
287						alias: Some(alias),
288					},
289					None,
290				)),
291				other => Ok((other, Some(alias))),
292			}
293		} else {
294			Ok((from, None))
295		}
296	}
297
298	fn parse_cte_list(&mut self) -> Result<Vec<CteDefinition>, Error> {
299		self.expect_keyword(Keyword::With)?;
300		if self.at_keyword(&Keyword::Recursive) {
301			return Err(Error("recursive CTEs are not supported".into()));
302		}
303		let mut ctes = Vec::new();
304		loop {
305			let name = self.expect_ident()?;
306			self.expect_keyword(Keyword::As)?;
307			self.expect_token(Token::OpenParen)?;
308			let query = self.parse_select_statement()?;
309			self.expect_token(Token::CloseParen)?;
310			ctes.push(CteDefinition {
311				name,
312				query,
313			});
314			if self.at_token(&Token::Comma) {
315				self.advance()?;
316			} else {
317				break;
318			}
319		}
320		Ok(ctes)
321	}
322
323	fn parse_select_columns(&mut self) -> Result<Vec<SelectColumn>, Error> {
324		let mut cols = Vec::new();
325		loop {
326			if self.at_token(&Token::Asterisk) {
327				self.advance()?;
328				cols.push(SelectColumn::AllColumns);
329			} else if self.is_eof()
330				|| self.at_keyword(&Keyword::From)
331				|| self.at_keyword(&Keyword::Where)
332				|| self.at_keyword(&Keyword::Order)
333				|| self.at_keyword(&Keyword::Limit)
334				|| self.at_keyword(&Keyword::Group)
335				|| self.at_keyword(&Keyword::Having)
336				|| self.at_keyword(&Keyword::Union)
337				|| self.at_keyword(&Keyword::Intersect)
338				|| self.at_keyword(&Keyword::Except)
339				|| self.at_token(&Token::Semicolon)
340				|| self.at_token(&Token::CloseParen)
341			{
342				break;
343			} else {
344				let expr = self.parse_expr()?;
345				let alias = if self.at_keyword(&Keyword::As) {
346					self.advance()?;
347					Some(self.expect_ident()?)
348				} else {
349					None
350				};
351				cols.push(SelectColumn::Expr {
352					expr,
353					alias,
354				});
355			}
356
357			if self.at_token(&Token::Comma) {
358				self.advance()?;
359			} else {
360				break;
361			}
362		}
363		Ok(cols)
364	}
365
366	fn parse_from_clause(&mut self) -> Result<FromClause, Error> {
367		let (from, _alias) = self.parse_from_item()?;
368		Ok(from)
369	}
370
371	fn parse_join_if_present(&mut self) -> Result<bool, Error> {
372		if self.is_eof() {
373			return Ok(false);
374		}
375
376		if self.at_keyword(&Keyword::Join) {
377			return Ok(true);
378		}
379
380		if self.at_keyword(&Keyword::Inner)
381			|| self.at_keyword(&Keyword::Left)
382			|| self.at_keyword(&Keyword::Right)
383			|| self.at_keyword(&Keyword::Cross)
384			|| self.at_keyword(&Keyword::Natural)
385			|| self.at_keyword(&Keyword::Full)
386		{
387			let mut look = self.pos + 1;
388			if look < self.tokens.len() && self.tokens[look] == Token::Keyword(Keyword::Outer) {
389				look += 1;
390			}
391			if look < self.tokens.len() && self.tokens[look] == Token::Keyword(Keyword::Join) {
392				return Ok(true);
393			}
394		}
395		Ok(false)
396	}
397
398	fn finish_parse_join(&mut self) -> Result<JoinClause, Error> {
399		let join_type = if self.at_keyword(&Keyword::Left) {
400			self.advance()?;
401			if self.at_keyword(&Keyword::Outer) {
402				self.advance()?;
403			}
404			self.expect_keyword(Keyword::Join)?;
405			JoinType::Left
406		} else if self.at_keyword(&Keyword::Inner) {
407			self.advance()?;
408			self.expect_keyword(Keyword::Join)?;
409			JoinType::Inner
410		} else if self.at_keyword(&Keyword::Cross) {
411			self.advance()?;
412			self.expect_keyword(Keyword::Join)?;
413			JoinType::Cross
414		} else if self.at_keyword(&Keyword::Natural) {
415			self.advance()?;
416			self.expect_keyword(Keyword::Join)?;
417			JoinType::Inner
418		} else if self.at_keyword(&Keyword::Right) || self.at_keyword(&Keyword::Full) {
419			self.advance()?;
420			if self.at_keyword(&Keyword::Outer) {
421				self.advance()?;
422			}
423			self.expect_keyword(Keyword::Join)?;
424			JoinType::Inner
425		} else {
426			self.expect_keyword(Keyword::Join)?;
427			JoinType::Inner
428		};
429
430		let table = self.parse_from_clause()?;
431		let table_alias = if self.at_keyword(&Keyword::As) {
432			self.advance()?;
433			Some(self.expect_ident()?)
434		} else if !self.is_eof() && self.is_ident_like() && !self.at_keyword(&Keyword::On) {
435			Some(self.expect_ident()?)
436		} else {
437			match &table {
438				FromClause::Table {
439					alias,
440					..
441				} => alias.clone(),
442				_ => None,
443			}
444		};
445
446		let on = if self.at_keyword(&Keyword::On) {
447			self.advance()?;
448			self.parse_expr()?
449		} else {
450			Expr::BoolLiteral(true)
451		};
452
453		Ok(JoinClause {
454			join_type,
455			table,
456			table_alias,
457			on,
458		})
459	}
460
461	fn parse_insert(&mut self) -> Result<Statement, Error> {
462		self.expect_keyword(Keyword::Insert)?;
463		self.expect_keyword(Keyword::Into)?;
464
465		let (shape, table) = self.parse_table_name()?;
466
467		let columns = if self.at_token(&Token::OpenParen) {
468			self.advance()?;
469			let cols = self.parse_ident_list()?;
470			self.expect_token(Token::CloseParen)?;
471			cols
472		} else {
473			vec![]
474		};
475
476		if self.at_keyword(&Keyword::Select) || self.at_keyword(&Keyword::With) {
477			let sel = self.parse_select_statement()?;
478			return Ok(Statement::Insert(InsertStatement {
479				table,
480				shape,
481				columns,
482				source: InsertSource::Select(Box::new(sel)),
483			}));
484		}
485
486		self.expect_keyword(Keyword::Values)?;
487
488		let mut values = Vec::new();
489		loop {
490			self.expect_token(Token::OpenParen)?;
491			let row = self.parse_expr_list()?;
492			self.expect_token(Token::CloseParen)?;
493			values.push(row);
494			if self.at_token(&Token::Comma) {
495				self.advance()?;
496			} else {
497				break;
498			}
499		}
500
501		Ok(Statement::Insert(InsertStatement {
502			table,
503			shape,
504			columns,
505			source: InsertSource::Values(values),
506		}))
507	}
508
509	fn parse_update(&mut self) -> Result<Statement, Error> {
510		self.expect_keyword(Keyword::Update)?;
511		let (shape, table) = self.parse_table_name()?;
512		self.expect_keyword(Keyword::Set)?;
513
514		let mut assignments = Vec::new();
515		loop {
516			let col = self.expect_ident()?;
517			self.expect_token(Token::Eq)?;
518			let val = self.parse_expr()?;
519			assignments.push((col, val));
520			if self.at_token(&Token::Comma) {
521				self.advance()?;
522			} else {
523				break;
524			}
525		}
526
527		let where_clause = if self.at_keyword(&Keyword::Where) {
528			self.advance()?;
529			Some(self.parse_expr()?)
530		} else {
531			None
532		};
533
534		Ok(Statement::Update(UpdateStatement {
535			table,
536			shape,
537			assignments,
538			where_clause,
539		}))
540	}
541
542	fn parse_delete(&mut self) -> Result<Statement, Error> {
543		self.expect_keyword(Keyword::Delete)?;
544		self.expect_keyword(Keyword::From)?;
545		let (shape, table) = self.parse_table_name()?;
546
547		let where_clause = if self.at_keyword(&Keyword::Where) {
548			self.advance()?;
549			Some(self.parse_expr()?)
550		} else {
551			None
552		};
553
554		Ok(Statement::Delete(DeleteStatement {
555			table,
556			shape,
557			where_clause,
558		}))
559	}
560
561	fn parse_create(&mut self) -> Result<Statement, Error> {
562		self.expect_keyword(Keyword::Create)?;
563
564		if self.at_keyword(&Keyword::Unique) {
565			self.advance()?;
566			self.expect_keyword(Keyword::Index)?;
567			return self.parse_create_index(true);
568		}
569
570		if self.at_keyword(&Keyword::Index) {
571			self.advance()?;
572			return self.parse_create_index(false);
573		}
574
575		self.expect_keyword(Keyword::Table)?;
576
577		let if_not_exists = if self.at_keyword(&Keyword::If) {
578			self.advance()?;
579			self.expect_keyword(Keyword::Not)?;
580			self.expect_keyword(Keyword::Exists)?;
581			true
582		} else {
583			false
584		};
585
586		let (shape, table) = self.parse_table_name()?;
587
588		self.expect_token(Token::OpenParen)?;
589		let mut columns = Vec::new();
590		let mut primary_key = Vec::new();
591		loop {
592			if self.at_token(&Token::CloseParen) {
593				break;
594			}
595
596			if self.at_keyword(&Keyword::Primary) {
597				self.advance()?;
598				self.expect_keyword(Keyword::Key)?;
599				self.expect_token(Token::OpenParen)?;
600				primary_key = self.parse_ident_list()?;
601				self.expect_token(Token::CloseParen)?;
602				if self.at_token(&Token::Comma) {
603					self.advance()?;
604				}
605				continue;
606			}
607
608			if self.at_keyword(&Keyword::Unique) {
609				self.advance()?;
610				self.expect_token(Token::OpenParen)?;
611				let _cols = self.parse_ident_list()?;
612				self.expect_token(Token::CloseParen)?;
613				if self.at_token(&Token::Comma) {
614					self.advance()?;
615				}
616				continue;
617			}
618			let name = self.expect_ident()?;
619			let data_type = self.parse_sql_type()?;
620			let mut nullable = true;
621			if self.at_keyword(&Keyword::Not) {
622				self.advance()?;
623				self.expect_keyword(Keyword::Null)?;
624				nullable = false;
625			} else if self.at_keyword(&Keyword::Null) {
626				self.advance()?;
627				nullable = true;
628			}
629
630			if self.at_keyword(&Keyword::Primary) {
631				self.advance()?;
632				self.expect_keyword(Keyword::Key)?;
633				primary_key.push(name.clone());
634				nullable = false;
635			}
636
637			if self.at_keyword(&Keyword::Unique) {
638				self.advance()?;
639			}
640
641			columns.push(Column {
642				name,
643				data_type,
644				nullable,
645			});
646			if self.at_token(&Token::Comma) {
647				self.advance()?;
648			} else {
649				break;
650			}
651		}
652		self.expect_token(Token::CloseParen)?;
653
654		Ok(Statement::CreateTable(CreateTableStatement {
655			table,
656			shape,
657			columns,
658			primary_key,
659			if_not_exists,
660		}))
661	}
662
663	fn parse_create_index(&mut self, unique: bool) -> Result<Statement, Error> {
664		if self.at_keyword(&Keyword::If) {
665			self.advance()?;
666			self.expect_keyword(Keyword::Not)?;
667			self.expect_keyword(Keyword::Exists)?;
668		}
669
670		let index_name = self.expect_ident()?;
671		self.expect_keyword(Keyword::On)?;
672		let (shape, table) = self.parse_table_name()?;
673
674		self.expect_token(Token::OpenParen)?;
675		let mut columns = Vec::new();
676		loop {
677			let name = self.expect_ident()?;
678			let direction = if self.at_keyword(&Keyword::Asc) {
679				self.advance()?;
680				Some(OrderDirection::Asc)
681			} else if self.at_keyword(&Keyword::Desc) {
682				self.advance()?;
683				Some(OrderDirection::Desc)
684			} else {
685				None
686			};
687			columns.push(IndexColumn {
688				name,
689				direction,
690			});
691			if self.at_token(&Token::Comma) {
692				self.advance()?;
693			} else {
694				break;
695			}
696		}
697		self.expect_token(Token::CloseParen)?;
698
699		if self.at_keyword(&Keyword::Where) {
700			self.advance()?;
701			let _ = self.parse_expr()?;
702		}
703
704		Ok(Statement::CreateIndex(CreateIndexStatement {
705			unique,
706			index_name,
707			table,
708			shape,
709			columns,
710		}))
711	}
712
713	fn parse_drop(&mut self) -> Result<Statement, Error> {
714		self.expect_keyword(Keyword::Drop)?;
715
716		if self.at_keyword(&Keyword::Index) {
717			self.advance()?;
718
719			let _if_exists = if self.at_keyword(&Keyword::If) {
720				self.advance()?;
721				self.expect_keyword(Keyword::Exists)?;
722				true
723			} else {
724				false
725			};
726			let index_name = self.expect_ident()?;
727
728			return Ok(Statement::DropTable(DropTableStatement {
729				table: index_name,
730				shape: None,
731				if_exists: _if_exists,
732			}));
733		}
734
735		self.expect_keyword(Keyword::Table)?;
736
737		let if_exists = if self.at_keyword(&Keyword::If) {
738			self.advance()?;
739			self.expect_keyword(Keyword::Exists)?;
740			true
741		} else {
742			false
743		};
744
745		let (shape, table) = self.parse_table_name()?;
746
747		Ok(Statement::DropTable(DropTableStatement {
748			table,
749			shape,
750			if_exists,
751		}))
752	}
753
754	fn parse_sql_type(&mut self) -> Result<SqlType, Error> {
755		let tok = self.advance()?;
756		match tok {
757			Token::Keyword(Keyword::Int) => Ok(SqlType::Int),
758			Token::Keyword(Keyword::Int2) => Ok(SqlType::Int2),
759			Token::Keyword(Keyword::Int4) => Ok(SqlType::Int4),
760			Token::Keyword(Keyword::Int8) => Ok(SqlType::Int8),
761			Token::Keyword(Keyword::Smallint) => Ok(SqlType::Smallint),
762			Token::Keyword(Keyword::Integer) => Ok(SqlType::Integer),
763			Token::Keyword(Keyword::Bigint) => Ok(SqlType::Bigint),
764			Token::Keyword(Keyword::Float4) => Ok(SqlType::Float4),
765			Token::Keyword(Keyword::Float8) => Ok(SqlType::Float8),
766			Token::Keyword(Keyword::FloatKw) => Ok(SqlType::FloatType),
767			Token::Keyword(Keyword::Numeric) => Ok(SqlType::Numeric),
768			Token::Keyword(Keyword::Real) => Ok(SqlType::Real),
769			Token::Keyword(Keyword::Double) => {
770				if self.at_keyword(&Keyword::Precision) {
771					self.advance()?;
772				}
773				Ok(SqlType::Double)
774			}
775			Token::Keyword(Keyword::Boolean) => Ok(SqlType::Boolean),
776			Token::Keyword(Keyword::Bool) => Ok(SqlType::Bool),
777			Token::Keyword(Keyword::Text) => Ok(SqlType::Text),
778			Token::Keyword(Keyword::Utf8) => Ok(SqlType::Utf8),
779			Token::Keyword(Keyword::Blob) => Ok(SqlType::Blob),
780			Token::Keyword(Keyword::Varchar) => {
781				let len = if self.at_token(&Token::OpenParen) {
782					self.advance()?;
783					let n = self.parse_u64()?;
784					self.expect_token(Token::CloseParen)?;
785					Some(n)
786				} else {
787					None
788				};
789				Ok(SqlType::Varchar(len))
790			}
791			Token::Keyword(Keyword::Char) => {
792				let len = if self.at_token(&Token::OpenParen) {
793					self.advance()?;
794					let n = self.parse_u64()?;
795					self.expect_token(Token::CloseParen)?;
796					Some(n)
797				} else {
798					None
799				};
800				Ok(SqlType::Char(len))
801			}
802			_ => Err(Error(format!("expected SQL type, got {tok:?}"))),
803		}
804	}
805
806	fn parse_expr(&mut self) -> Result<Expr, Error> {
807		self.parse_or()
808	}
809
810	fn parse_or(&mut self) -> Result<Expr, Error> {
811		let mut left = self.parse_and()?;
812		while self.at_keyword(&Keyword::Or) {
813			self.advance()?;
814			let right = self.parse_and()?;
815			left = Expr::BinaryOp {
816				left: Box::new(left),
817				op: BinaryOp::Or,
818				right: Box::new(right),
819			};
820		}
821		Ok(left)
822	}
823
824	fn parse_and(&mut self) -> Result<Expr, Error> {
825		let mut left = self.parse_not()?;
826		while self.at_keyword(&Keyword::And) {
827			self.advance()?;
828			let right = self.parse_not()?;
829			left = Expr::BinaryOp {
830				left: Box::new(left),
831				op: BinaryOp::And,
832				right: Box::new(right),
833			};
834		}
835		Ok(left)
836	}
837
838	fn parse_not(&mut self) -> Result<Expr, Error> {
839		if self.at_keyword(&Keyword::Not) {
840			if matches!(self.tokens.get(self.pos + 1), Some(Token::Keyword(Keyword::Exists))) {
841				self.advance()?;
842				self.advance()?;
843				self.expect_token(Token::OpenParen)?;
844				let sel = self.parse_select_statement()?;
845				self.expect_token(Token::CloseParen)?;
846				return Ok(Expr::UnaryOp {
847					op: UnaryOp::Not,
848					expr: Box::new(Expr::Exists(Box::new(sel))),
849				});
850			}
851			self.advance()?;
852			let expr = self.parse_not()?;
853			Ok(Expr::UnaryOp {
854				op: UnaryOp::Not,
855				expr: Box::new(expr),
856			})
857		} else {
858			self.parse_comparison()
859		}
860	}
861
862	fn parse_comparison(&mut self) -> Result<Expr, Error> {
863		let mut left = self.parse_addition()?;
864
865		if self.at_keyword(&Keyword::Is) {
866			self.advance()?;
867			if self.at_keyword(&Keyword::Not) {
868				self.advance()?;
869				self.expect_keyword(Keyword::Null)?;
870				return Ok(Expr::IsNull {
871					expr: Box::new(left),
872					negated: true,
873				});
874			} else {
875				self.expect_keyword(Keyword::Null)?;
876				return Ok(Expr::IsNull {
877					expr: Box::new(left),
878					negated: false,
879				});
880			}
881		}
882
883		if self.at_keyword(&Keyword::Not)
884			&& matches!(self.tokens.get(self.pos + 1), Some(Token::Keyword(Keyword::Between)))
885		{
886			self.advance()?;
887			self.advance()?;
888			let low = self.parse_addition()?;
889			self.expect_keyword(Keyword::And)?;
890			let high = self.parse_addition()?;
891			return Ok(Expr::Between {
892				expr: Box::new(left),
893				low: Box::new(low),
894				high: Box::new(high),
895				negated: true,
896			});
897		}
898
899		if self.at_keyword(&Keyword::Between) {
900			self.advance()?;
901			let low = self.parse_addition()?;
902			self.expect_keyword(Keyword::And)?;
903			let high = self.parse_addition()?;
904			return Ok(Expr::Between {
905				expr: Box::new(left),
906				low: Box::new(low),
907				high: Box::new(high),
908				negated: false,
909			});
910		}
911
912		if self.at_keyword(&Keyword::Not)
913			&& matches!(self.tokens.get(self.pos + 1), Some(Token::Keyword(Keyword::Like)))
914		{
915			self.advance()?;
916			self.advance()?;
917			let pattern = self.parse_addition()?;
918			return Ok(Expr::Like {
919				expr: Box::new(left),
920				pattern: Box::new(pattern),
921				negated: true,
922			});
923		}
924
925		if self.at_keyword(&Keyword::Like) {
926			self.advance()?;
927			let pattern = self.parse_addition()?;
928			return Ok(Expr::Like {
929				expr: Box::new(left),
930				pattern: Box::new(pattern),
931				negated: false,
932			});
933		}
934
935		if self.at_keyword(&Keyword::Not)
936			&& matches!(self.tokens.get(self.pos + 1), Some(Token::Keyword(Keyword::Glob)))
937		{
938			self.advance()?;
939			self.advance()?;
940			let pattern = self.parse_addition()?;
941			return Ok(Expr::Like {
942				expr: Box::new(left),
943				pattern: Box::new(pattern),
944				negated: true,
945			});
946		}
947
948		if self.at_keyword(&Keyword::Glob) {
949			self.advance()?;
950			let pattern = self.parse_addition()?;
951			return Ok(Expr::Like {
952				expr: Box::new(left),
953				pattern: Box::new(pattern),
954				negated: false,
955			});
956		}
957
958		if self.at_keyword(&Keyword::Not)
959			&& matches!(self.tokens.get(self.pos + 1), Some(Token::Keyword(Keyword::In)))
960		{
961			self.advance()?;
962			self.advance()?;
963			self.expect_token(Token::OpenParen)?;
964
965			if self.at_keyword(&Keyword::Select) || self.at_keyword(&Keyword::With) {
966				let sel = self.parse_select_statement()?;
967				self.expect_token(Token::CloseParen)?;
968				return Ok(Expr::InSelect {
969					expr: Box::new(left),
970					subquery: Box::new(sel),
971					negated: true,
972				});
973			}
974			let list = self.parse_expr_list()?;
975			self.expect_token(Token::CloseParen)?;
976			return Ok(Expr::InList {
977				expr: Box::new(left),
978				list,
979				negated: true,
980			});
981		}
982
983		if self.at_keyword(&Keyword::In) {
984			self.advance()?;
985			self.expect_token(Token::OpenParen)?;
986
987			if self.at_keyword(&Keyword::Select) || self.at_keyword(&Keyword::With) {
988				let sel = self.parse_select_statement()?;
989				self.expect_token(Token::CloseParen)?;
990				return Ok(Expr::InSelect {
991					expr: Box::new(left),
992					subquery: Box::new(sel),
993					negated: false,
994				});
995			}
996			let list = self.parse_expr_list()?;
997			self.expect_token(Token::CloseParen)?;
998			return Ok(Expr::InList {
999				expr: Box::new(left),
1000				list,
1001				negated: false,
1002			});
1003		}
1004
1005		let op = match self.tokens.get(self.pos) {
1006			Some(Token::Eq) => Some(BinaryOp::Eq),
1007			Some(Token::NotEq) => Some(BinaryOp::NotEq),
1008			Some(Token::Lt) => Some(BinaryOp::Lt),
1009			Some(Token::Gt) => Some(BinaryOp::Gt),
1010			Some(Token::LtEq) => Some(BinaryOp::LtEq),
1011			Some(Token::GtEq) => Some(BinaryOp::GtEq),
1012			_ => None,
1013		};
1014		if let Some(op) = op {
1015			self.advance()?;
1016			let right = self.parse_addition()?;
1017			left = Expr::BinaryOp {
1018				left: Box::new(left),
1019				op,
1020				right: Box::new(right),
1021			};
1022		}
1023
1024		Ok(left)
1025	}
1026
1027	fn parse_addition(&mut self) -> Result<Expr, Error> {
1028		let mut left = self.parse_multiplication()?;
1029		loop {
1030			let op = match self.tokens.get(self.pos) {
1031				Some(Token::Plus) => Some(BinaryOp::Add),
1032				Some(Token::Minus) => Some(BinaryOp::Sub),
1033				Some(Token::Concat) => Some(BinaryOp::Concat),
1034				_ => None,
1035			};
1036			if let Some(op) = op {
1037				self.advance()?;
1038				let right = self.parse_multiplication()?;
1039				left = Expr::BinaryOp {
1040					left: Box::new(left),
1041					op,
1042					right: Box::new(right),
1043				};
1044			} else {
1045				break;
1046			}
1047		}
1048		Ok(left)
1049	}
1050
1051	fn parse_multiplication(&mut self) -> Result<Expr, Error> {
1052		let mut left = self.parse_unary()?;
1053		loop {
1054			let op = match self.tokens.get(self.pos) {
1055				Some(Token::Asterisk) => Some(BinaryOp::Mul),
1056				Some(Token::Slash) => Some(BinaryOp::Div),
1057				Some(Token::Percent) => Some(BinaryOp::Mod),
1058				_ => None,
1059			};
1060			if let Some(op) = op {
1061				self.advance()?;
1062				let right = self.parse_unary()?;
1063				left = Expr::BinaryOp {
1064					left: Box::new(left),
1065					op,
1066					right: Box::new(right),
1067				};
1068			} else {
1069				break;
1070			}
1071		}
1072		Ok(left)
1073	}
1074
1075	fn parse_unary(&mut self) -> Result<Expr, Error> {
1076		if self.at_token(&Token::Minus) {
1077			self.advance()?;
1078			let expr = self.parse_unary()?;
1079			return Ok(Expr::UnaryOp {
1080				op: UnaryOp::Neg,
1081				expr: Box::new(expr),
1082			});
1083		}
1084
1085		if self.at_token(&Token::Plus) {
1086			self.advance()?;
1087			return self.parse_unary();
1088		}
1089		self.parse_primary()
1090	}
1091
1092	fn parse_primary(&mut self) -> Result<Expr, Error> {
1093		let tok = self.peek()?.clone();
1094		match tok {
1095			Token::Integer(n) => {
1096				self.advance()?;
1097				Ok(Expr::IntegerLiteral(n))
1098			}
1099			Token::Float(f) => {
1100				self.advance()?;
1101				Ok(Expr::FloatLiteral(f))
1102			}
1103			Token::StringLit(s) => {
1104				self.advance()?;
1105				Ok(Expr::StringLiteral(s))
1106			}
1107			Token::Keyword(Keyword::True) => {
1108				self.advance()?;
1109				Ok(Expr::BoolLiteral(true))
1110			}
1111			Token::Keyword(Keyword::False) => {
1112				self.advance()?;
1113				Ok(Expr::BoolLiteral(false))
1114			}
1115			Token::Keyword(Keyword::Null) => {
1116				self.advance()?;
1117				Ok(Expr::Null)
1118			}
1119			Token::Keyword(Keyword::Cast) => self.parse_cast_expr(),
1120			Token::Keyword(Keyword::Case) => self.parse_case_expr(),
1121			Token::Keyword(Keyword::Exists) => {
1122				self.advance()?;
1123				self.expect_token(Token::OpenParen)?;
1124				let sel = self.parse_select_statement()?;
1125				self.expect_token(Token::CloseParen)?;
1126				Ok(Expr::Exists(Box::new(sel)))
1127			}
1128			Token::Keyword(Keyword::Not) => {
1129				if matches!(self.tokens.get(self.pos + 1), Some(Token::Keyword(Keyword::Exists))) {
1130					self.advance()?;
1131					self.advance()?;
1132					self.expect_token(Token::OpenParen)?;
1133					let sel = self.parse_select_statement()?;
1134					self.expect_token(Token::CloseParen)?;
1135					Ok(Expr::UnaryOp {
1136						op: UnaryOp::Not,
1137						expr: Box::new(Expr::Exists(Box::new(sel))),
1138					})
1139				} else {
1140					Err(Error(format!("unexpected token in expression: {tok:?}")))
1141				}
1142			}
1143
1144			Token::Keyword(Keyword::Count)
1145			| Token::Keyword(Keyword::Sum)
1146			| Token::Keyword(Keyword::Avg)
1147			| Token::Keyword(Keyword::Min)
1148			| Token::Keyword(Keyword::Max) => {
1149				let name = keyword_to_string(match &self.advance()? {
1150					Token::Keyword(kw) => kw,
1151					_ => unreachable!(),
1152				});
1153				self.expect_token(Token::OpenParen)?;
1154
1155				let distinct_prefix = if self.at_keyword(&Keyword::Distinct) {
1156					self.advance()?;
1157					true
1158				} else {
1159					false
1160				};
1161				let args = if self.at_token(&Token::Asterisk) {
1162					self.advance()?;
1163					vec![Expr::Identifier("*".into())]
1164				} else {
1165					self.parse_expr_list()?
1166				};
1167				self.expect_token(Token::CloseParen)?;
1168				if distinct_prefix {
1169					Ok(Expr::FunctionCall {
1170						name: format!("{name}_DISTINCT"),
1171						args,
1172					})
1173				} else {
1174					Ok(Expr::FunctionCall {
1175						name,
1176						args,
1177					})
1178				}
1179			}
1180			Token::OpenParen => {
1181				self.advance()?;
1182
1183				if self.at_keyword(&Keyword::Select) || self.at_keyword(&Keyword::With) {
1184					let sel = self.parse_select_statement()?;
1185					self.expect_token(Token::CloseParen)?;
1186					return Ok(Expr::Subquery(Box::new(sel)));
1187				}
1188				let expr = self.parse_expr()?;
1189				self.expect_token(Token::CloseParen)?;
1190				Ok(Expr::Nested(Box::new(expr)))
1191			}
1192			Token::Ident(_) => {
1193				let name = self.expect_ident()?;
1194
1195				if self.at_token(&Token::Dot) {
1196					self.advance()?;
1197					let col = self.expect_ident()?;
1198
1199					if self.at_token(&Token::OpenParen) {
1200						self.advance()?;
1201						let args = if self.at_token(&Token::CloseParen) {
1202							vec![]
1203						} else if self.at_token(&Token::Asterisk) {
1204							self.advance()?;
1205							vec![Expr::Identifier("*".into())]
1206						} else {
1207							self.parse_expr_list()?
1208						};
1209						self.expect_token(Token::CloseParen)?;
1210						Ok(Expr::FunctionCall {
1211							name: format!("{name}.{col}"),
1212							args,
1213						})
1214					} else {
1215						Ok(Expr::QualifiedIdentifier(name, col))
1216					}
1217				} else if self.at_token(&Token::OpenParen) {
1218					self.advance()?;
1219					let args = if self.at_token(&Token::CloseParen) {
1220						vec![]
1221					} else if self.at_token(&Token::Asterisk) {
1222						self.advance()?;
1223						vec![Expr::Identifier("*".into())]
1224					} else {
1225						self.parse_expr_list()?
1226					};
1227					self.expect_token(Token::CloseParen)?;
1228					Ok(Expr::FunctionCall {
1229						name,
1230						args,
1231					})
1232				} else {
1233					Ok(Expr::Identifier(name))
1234				}
1235			}
1236			_ => Err(Error(format!("unexpected token in expression: {tok:?}"))),
1237		}
1238	}
1239
1240	fn parse_cast_expr(&mut self) -> Result<Expr, Error> {
1241		self.expect_keyword(Keyword::Cast)?;
1242		self.expect_token(Token::OpenParen)?;
1243		let expr = self.parse_expr()?;
1244		self.expect_keyword(Keyword::As)?;
1245		let data_type = self.parse_sql_type()?;
1246		self.expect_token(Token::CloseParen)?;
1247		Ok(Expr::Cast {
1248			expr: Box::new(expr),
1249			data_type,
1250		})
1251	}
1252
1253	fn parse_case_expr(&mut self) -> Result<Expr, Error> {
1254		self.expect_keyword(Keyword::Case)?;
1255
1256		let operand = if !self.at_keyword(&Keyword::When) {
1257			Some(Box::new(self.parse_expr()?))
1258		} else {
1259			None
1260		};
1261
1262		let mut when_clauses = Vec::new();
1263		while self.at_keyword(&Keyword::When) {
1264			self.advance()?;
1265			let condition = self.parse_expr()?;
1266			self.expect_keyword(Keyword::Then)?;
1267			let result = self.parse_expr()?;
1268			when_clauses.push((condition, result));
1269		}
1270
1271		let else_clause = if self.at_keyword(&Keyword::Else) {
1272			self.advance()?;
1273			Some(Box::new(self.parse_expr()?))
1274		} else {
1275			None
1276		};
1277
1278		self.expect_keyword(Keyword::End)?;
1279
1280		Ok(Expr::Case {
1281			operand,
1282			when_clauses,
1283			else_clause,
1284		})
1285	}
1286
1287	fn parse_expr_list(&mut self) -> Result<Vec<Expr>, Error> {
1288		let mut exprs = Vec::new();
1289		exprs.push(self.parse_expr()?);
1290		while self.at_token(&Token::Comma) {
1291			self.advance()?;
1292			exprs.push(self.parse_expr()?);
1293		}
1294		Ok(exprs)
1295	}
1296
1297	fn parse_ident_list(&mut self) -> Result<Vec<String>, Error> {
1298		let mut names = Vec::new();
1299		names.push(self.expect_ident()?);
1300		while self.at_token(&Token::Comma) {
1301			self.advance()?;
1302			names.push(self.expect_ident()?);
1303		}
1304		Ok(names)
1305	}
1306
1307	fn parse_order_by_list(&mut self) -> Result<Vec<OrderByItem>, Error> {
1308		let mut items = Vec::new();
1309		loop {
1310			let expr = self.parse_expr()?;
1311			let direction = if self.at_keyword(&Keyword::Desc) {
1312				self.advance()?;
1313				OrderDirection::Desc
1314			} else {
1315				if self.at_keyword(&Keyword::Asc) {
1316					self.advance()?;
1317				}
1318				OrderDirection::Asc
1319			};
1320			items.push(OrderByItem {
1321				expr,
1322				direction,
1323			});
1324			if self.at_token(&Token::Comma) {
1325				self.advance()?;
1326			} else {
1327				break;
1328			}
1329		}
1330		Ok(items)
1331	}
1332
1333	fn parse_u64(&mut self) -> Result<u64, Error> {
1334		let tok = self.advance()?;
1335		match tok {
1336			Token::Integer(n) if n >= 0 => Ok(n as u64),
1337			_ => Err(Error(format!("expected positive integer, got {tok:?}"))),
1338		}
1339	}
1340
1341	fn parse_table_name(&mut self) -> Result<(Option<String>, String), Error> {
1342		let name = self.expect_ident()?;
1343		if self.at_token(&Token::Dot) {
1344			self.advance()?;
1345			let table = self.expect_ident()?;
1346			Ok((Some(name), table))
1347		} else {
1348			Ok((None, name))
1349		}
1350	}
1351}
1352
1353fn is_structural_keyword(kw: &Keyword) -> bool {
1354	matches!(
1355		kw,
1356		Keyword::Where
1357			| Keyword::Order | Keyword::Group
1358			| Keyword::Having | Keyword::Limit
1359			| Keyword::Offset | Keyword::Join
1360			| Keyword::Inner | Keyword::Left
1361			| Keyword::Right | Keyword::Cross
1362			| Keyword::Outer | Keyword::Full
1363			| Keyword::Natural | Keyword::On
1364			| Keyword::Set | Keyword::Values
1365			| Keyword::Select | Keyword::From
1366			| Keyword::Union | Keyword::Intersect
1367			| Keyword::Except | Keyword::When
1368			| Keyword::Then | Keyword::Else
1369			| Keyword::End | Keyword::And
1370			| Keyword::Or | Keyword::Not
1371	)
1372}
1373
1374fn keyword_to_string(kw: &Keyword) -> String {
1375	match kw {
1376		Keyword::Select => "SELECT",
1377		Keyword::From => "FROM",
1378		Keyword::Where => "WHERE",
1379		Keyword::And => "AND",
1380		Keyword::Or => "OR",
1381		Keyword::Not => "NOT",
1382		Keyword::As => "AS",
1383		Keyword::Order => "ORDER",
1384		Keyword::By => "BY",
1385		Keyword::Asc => "ASC",
1386		Keyword::Desc => "DESC",
1387		Keyword::Limit => "LIMIT",
1388		Keyword::Offset => "OFFSET",
1389		Keyword::Group => "GROUP",
1390		Keyword::Having => "HAVING",
1391		Keyword::Distinct => "DISTINCT",
1392		Keyword::Insert => "INSERT",
1393		Keyword::Into => "INTO",
1394		Keyword::Values => "VALUES",
1395		Keyword::Update => "UPDATE",
1396		Keyword::Set => "SET",
1397		Keyword::Delete => "DELETE",
1398		Keyword::Create => "CREATE",
1399		Keyword::Table => "TABLE",
1400		Keyword::Join => "JOIN",
1401		Keyword::Inner => "INNER",
1402		Keyword::Left => "LEFT",
1403		Keyword::Right => "RIGHT",
1404		Keyword::On => "ON",
1405		Keyword::Null => "NULL",
1406		Keyword::True => "true",
1407		Keyword::False => "false",
1408		Keyword::Is => "IS",
1409		Keyword::In => "IN",
1410		Keyword::Between => "BETWEEN",
1411		Keyword::Cast => "CAST",
1412		Keyword::Count => "COUNT",
1413		Keyword::Sum => "SUM",
1414		Keyword::Avg => "AVG",
1415		Keyword::Min => "MIN",
1416		Keyword::Max => "MAX",
1417		Keyword::Int => "INT",
1418		Keyword::Int2 => "INT2",
1419		Keyword::Int4 => "INT4",
1420		Keyword::Int8 => "INT8",
1421		Keyword::Smallint => "SMALLINT",
1422		Keyword::Integer => "INTEGER",
1423		Keyword::Bigint => "BIGINT",
1424		Keyword::Float4 => "FLOAT4",
1425		Keyword::Float8 => "FLOAT8",
1426		Keyword::Real => "REAL",
1427		Keyword::Double => "DOUBLE",
1428		Keyword::Precision => "PRECISION",
1429		Keyword::Boolean => "BOOLEAN",
1430		Keyword::Bool => "BOOL",
1431		Keyword::Varchar => "VARCHAR",
1432		Keyword::Text => "TEXT",
1433		Keyword::Char => "CHAR",
1434		Keyword::Utf8 => "UTF8",
1435		Keyword::Blob => "BLOB",
1436		Keyword::Primary => "PRIMARY",
1437		Keyword::Key => "KEY",
1438		Keyword::With => "WITH",
1439		Keyword::Recursive => "RECURSIVE",
1440		Keyword::Case => "CASE",
1441		Keyword::When => "WHEN",
1442		Keyword::Then => "THEN",
1443		Keyword::Else => "ELSE",
1444		Keyword::End => "END",
1445		Keyword::Exists => "EXISTS",
1446		Keyword::Union => "UNION",
1447		Keyword::All => "ALL",
1448		Keyword::Intersect => "INTERSECT",
1449		Keyword::Except => "EXCEPT",
1450		Keyword::Like => "LIKE",
1451		Keyword::Glob => "GLOB",
1452		Keyword::If => "IF",
1453		Keyword::FloatKw => "FLOAT",
1454		Keyword::Index => "INDEX",
1455		Keyword::Unique => "UNIQUE",
1456		Keyword::Drop => "DROP",
1457		Keyword::Cross => "CROSS",
1458		Keyword::Outer => "OUTER",
1459		Keyword::Full => "FULL",
1460		Keyword::Natural => "NATURAL",
1461		Keyword::Numeric => "NUMERIC",
1462	}
1463	.into()
1464}
1465
1466#[cfg(test)]
1467mod tests {
1468	use super::*;
1469	use crate::token::tokenize;
1470
1471	#[test]
1472	fn test_parse_simple_select() {
1473		let tokens = tokenize("SELECT id, name FROM users").unwrap();
1474		let stmt = Parser::new(tokens).parse().unwrap();
1475		match stmt {
1476			Statement::Select(sel) => {
1477				assert_eq!(sel.columns.len(), 2);
1478				assert!(sel.from.is_some());
1479			}
1480			_ => panic!("expected select"),
1481		}
1482	}
1483
1484	#[test]
1485	fn test_parse_select_star() {
1486		let tokens = tokenize("SELECT * FROM users").unwrap();
1487		let stmt = Parser::new(tokens).parse().unwrap();
1488		match stmt {
1489			Statement::Select(sel) => {
1490				assert!(matches!(sel.columns[0], SelectColumn::AllColumns));
1491			}
1492			_ => panic!("expected select"),
1493		}
1494	}
1495
1496	#[test]
1497	fn test_parse_where() {
1498		let tokens = tokenize("SELECT * FROM users WHERE age > 18").unwrap();
1499		let stmt = Parser::new(tokens).parse().unwrap();
1500		match stmt {
1501			Statement::Select(sel) => {
1502				assert!(sel.where_clause.is_some());
1503			}
1504			_ => panic!("expected select"),
1505		}
1506	}
1507
1508	#[test]
1509	fn test_parse_insert() {
1510		let tokens = tokenize("INSERT INTO users (id, name) VALUES (1, 'Alice')").unwrap();
1511		let stmt = Parser::new(tokens).parse().unwrap();
1512		match stmt {
1513			Statement::Insert(ins) => {
1514				assert_eq!(ins.table, "users");
1515				assert_eq!(ins.columns.len(), 2);
1516				match &ins.source {
1517					InsertSource::Values(v) => assert_eq!(v.len(), 1),
1518					_ => panic!("expected values"),
1519				}
1520			}
1521			_ => panic!("expected insert"),
1522		}
1523	}
1524}