inillucent_sql/parser/mod.rs
1//! The recursive-descent statement parser.
2//!
3//! Invariant: the parser performs no I/O and consults no catalog. It turns
4//! bytes into an arena tree and nothing else, which is what lets a syntax error
5//! be reported before a file is opened and lets the same parser run inside the
6//! catalog loader on the CREATE text stored in `sqlite_schema`.
7//!
8//! Depth is bounded before allocation rather than after: every recursive entry
9//! charges the expression-depth limit, so an adversarial `((((((...` fails with
10//! a limit error at a known offset instead of growing the arena until something
11//! else notices.
12//!
13//! One call parses one statement and reports how many bytes it consumed, which
14//! is SQLite's prepare contract: the caller gets a statement and the unused
15//! tail, and an empty statement succeeds with no program.
16
17mod ddl;
18mod dml;
19mod expr;
20mod select;
21
22use inillucent_base::limits::{Limit, Limits};
23
24use crate::ast::{Ast, NameId, Statement};
25use crate::diagnostic::{ParseError, ParseErrorKind};
26use crate::keyword::Keyword;
27use crate::lexer::{self, Lexer, Punctuator, QuoteForm, Span, Token, TokenKind};
28
29/// Where a statement's parameters ended up.
30#[derive(Clone, Debug, Default, PartialEq, Eq)]
31pub struct ParameterMap {
32 /// The highest parameter index the statement used.
33 pub count: u32,
34 /// Named parameters and the index each was assigned.
35 pub names: Vec<(Vec<u8>, u32)>,
36}
37
38impl ParameterMap {
39 /// Returns the index a named parameter was assigned.
40 pub fn index_of(&self, name: &[u8]) -> Option<u32> {
41 self.names
42 .iter()
43 .find(|(candidate, _)| candidate == name)
44 .map(|(_, index)| *index)
45 }
46}
47
48/// One parsed statement and everything the caller needs to continue.
49#[derive(Clone, Debug)]
50pub struct ParsedStatement {
51 /// The arena holding every node.
52 pub ast: Ast,
53 /// The statement itself.
54 pub statement: Statement,
55 /// How many bytes of the source this statement consumed, including its
56 /// terminating semicolon and any trivia before the next statement.
57 pub consumed: usize,
58 /// The parameters the statement declared.
59 pub parameters: ParameterMap,
60 /// The span of the statement text itself, without the trailing trivia.
61 pub span: Span,
62}
63
64/// What a statement is, decided without a full parse.
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub enum StatementClass {
67 /// The statement reads and does not write.
68 ReadOnly,
69 /// The statement writes.
70 Write,
71 /// The statement changes the schema.
72 SchemaChange,
73 /// The statement controls a transaction.
74 TransactionControl,
75 /// The statement is a PRAGMA, which may do either.
76 Pragma,
77 /// There is no statement here.
78 Empty,
79 /// The text does not begin a statement at all.
80 Unknown,
81}
82
83/// The parser: a lexer, a token buffer, an arena, and a depth charge.
84pub struct Parser<'a> {
85 source: &'a [u8],
86 lexer: Lexer<'a>,
87 buffer: Vec<Token>,
88 ast: Ast,
89 limits: &'a Limits,
90 depth: i64,
91 parameters: ParameterMap,
92 /// How many `SELECT`s this parse has read.
93 ///
94 /// **A counter rather than a walk over what was parsed.** `CHECK` is the
95 /// one place the grammar has to know whether an expression contained a
96 /// subquery, and comparing this before and after the expression answers it
97 /// exactly - where a recursive scan of the arena would be a second
98 /// enumeration of every expression node, to be kept in step with the first
99 /// for ever. See `no_subquery_in_check`.
100 selects: u64,
101}
102
103impl<'a> Parser<'a> {
104 /// Returns a parser positioned at an offset in the source.
105 pub fn new(source: &'a [u8], offset: usize, limits: &'a Limits) -> Parser<'a> {
106 Parser::with_arena(source, offset, limits, Ast::new())
107 }
108
109 /// Returns a parser that fills an arena the caller supplies.
110 ///
111 /// **For a caller that parses one statement after another.** The arena is
112 /// cleared rather than dropped, so the second parse pushes into capacity
113 /// the first one took - see [`Ast::clear`]. Nothing else differs: the arena
114 /// is filled and handed back exactly as `new`'s own is.
115 ///
116 /// @param source - the SQL text
117 /// @param offset - where in it this statement starts
118 /// @param limits - the limits to enforce
119 /// @param arena - the arena to fill, cleared first
120 pub fn with_arena(
121 source: &'a [u8],
122 offset: usize,
123 limits: &'a Limits,
124 mut arena: Ast,
125 ) -> Parser<'a> {
126 arena.clear();
127 Parser {
128 source,
129 lexer: Lexer::at(source, offset),
130 buffer: Vec::new(),
131 ast: arena,
132 limits,
133 depth: 0,
134 parameters: ParameterMap::default(),
135 selects: 0,
136 }
137 }
138
139 /// Returns the arena, for a caller that owns the parse.
140 pub fn into_ast(self) -> Ast {
141 self.ast
142 }
143
144 /// Returns the source being parsed.
145 pub fn source(&self) -> &'a [u8] {
146 self.source
147 }
148
149 /// Fills the lookahead buffer to at least `wanted` tokens.
150 fn fill(&mut self, wanted: usize) -> Result<(), ParseError> {
151 while self.buffer.len() < wanted {
152 let token = self.lexer.next_token()?;
153 let end = token.kind == TokenKind::EndOfInput;
154 self.buffer.push(token);
155 if end {
156 break;
157 }
158 }
159 Ok(())
160 }
161
162 /// Returns the token `ahead` positions from the cursor.
163 fn peek_at(&mut self, ahead: usize) -> Result<Token, ParseError> {
164 self.fill(ahead.saturating_add(1))?;
165 Ok(self.buffer.get(ahead).copied().unwrap_or(Token {
166 kind: TokenKind::EndOfInput,
167 span: Span::at(self.source.len()),
168 }))
169 }
170
171 /// Returns the next token without consuming it.
172 fn peek(&mut self) -> Result<Token, ParseError> {
173 self.peek_at(0)
174 }
175
176 /// Consumes and returns the next token.
177 fn bump(&mut self) -> Result<Token, ParseError> {
178 let token = self.peek()?;
179 if token.kind != TokenKind::EndOfInput && !self.buffer.is_empty() {
180 self.buffer.remove(0);
181 }
182 Ok(token)
183 }
184
185 /// Returns the byte offset the cursor sits at.
186 fn cursor(&mut self) -> usize {
187 match self.buffer.first() {
188 Some(token) => token.span.start as usize,
189 None => self.lexer.offset(),
190 }
191 }
192
193 /// Returns whether the next token spells a keyword.
194 fn at_keyword(&mut self, keyword: Keyword) -> Result<bool, ParseError> {
195 Ok(self.peek()?.keyword() == Some(keyword))
196 }
197
198 /// Returns whether the token `ahead` positions away spells a keyword.
199 fn at_keyword_ahead(&mut self, ahead: usize, keyword: Keyword) -> Result<bool, ParseError> {
200 Ok(self.peek_at(ahead)?.keyword() == Some(keyword))
201 }
202
203 /// Consumes a keyword if it is next, reporting whether it was.
204 fn eat_keyword(&mut self, keyword: Keyword) -> Result<bool, ParseError> {
205 if self.at_keyword(keyword)? {
206 self.bump()?;
207 return Ok(true);
208 }
209 Ok(false)
210 }
211
212 /// Consumes a keyword, failing with the keyword as the expected set.
213 fn expect_keyword(&mut self, keyword: Keyword) -> Result<Token, ParseError> {
214 if self.at_keyword(keyword)? {
215 return self.bump();
216 }
217 Err(self.unexpected(&[keyword.as_str()])?)
218 }
219
220 /// Returns whether the next token is a punctuator.
221 fn at(&mut self, punctuator: Punctuator) -> Result<bool, ParseError> {
222 Ok(self.peek()?.is(punctuator))
223 }
224
225 /// Consumes a punctuator if it is next, reporting whether it was.
226 fn eat(&mut self, punctuator: Punctuator) -> Result<bool, ParseError> {
227 if self.at(punctuator)? {
228 self.bump()?;
229 return Ok(true);
230 }
231 Ok(false)
232 }
233
234 /// Consumes a punctuator, failing with it as the expected set.
235 fn expect(&mut self, punctuator: Punctuator) -> Result<Token, ParseError> {
236 if self.at(punctuator)? {
237 return self.bump();
238 }
239 Err(self.unexpected(&[punctuator.as_str()])?)
240 }
241
242 /// Builds the failure for whatever token is next.
243 fn unexpected(&mut self, expected: &[&'static str]) -> Result<ParseError, ParseError> {
244 let token = self.peek()?;
245 let kind = if token.kind == TokenKind::EndOfInput {
246 ParseErrorKind::UnexpectedEnd {
247 expected: expected.to_vec(),
248 }
249 } else {
250 ParseErrorKind::Unexpected {
251 found: String::from_utf8_lossy(token.text(self.source)).into_owned(),
252 expected: expected.to_vec(),
253 }
254 };
255 Ok(ParseError::new(kind, token.span))
256 }
257
258 /// Charges one level of recursion against the parser's own depth limit.
259 ///
260 /// **Not `ExprDepth`, which is a different measurement.** This counts how
261 /// deep the recursive descent has gone; `ExprDepth` counts how deep the
262 /// expression *tree* is, and the two differ by every redundant
263 /// parenthesis - `((((1))))` is four of one and one of the other. Charging
264 /// the parser's recursion against the tree's limit refused
265 /// `SELECT ((( ... 1 ... )))` at a thousand parentheses, which the
266 /// reference accepts because its parser stack is allowed 2500.
267 fn enter(&mut self) -> Result<(), ParseError> {
268 self.depth = self.depth.saturating_add(1);
269 if self.depth > self.limits.get(Limit::ParserDepth) {
270 let span = Span::at(self.cursor());
271 return Err(ParseError::new(
272 ParseErrorKind::LimitExceeded("parser stack depth"),
273 span,
274 ));
275 }
276 Ok(())
277 }
278
279 /// Releases one level of recursion.
280 fn leave(&mut self) {
281 self.depth = self.depth.saturating_sub(1);
282 }
283
284 /// Charges the expression tree's own depth against `Limit::ExprDepth`.
285 ///
286 /// **`ExprDepth` was declared in `compat/limits.toml` and enforced nowhere
287 /// (task-1932, H8).** `enter`/`leave` above charge `ParserDepth`, which
288 /// counts recursion, and that is a different measurement: a flat chain
289 /// `a1 = 1 AND a2 = 2 AND ...` enters and leaves `parse_expr_bp` once per
290 /// term, so the recursion counter never accumulates, while the tree grows
291 /// one level per term with nothing counting it. Under the 1 GiB
292 /// `SqlLength` default that is a tree tens of millions of levels deep,
293 /// accepted here and then walked recursively by the binder, the planner and
294 /// the executor - each of which overflows the stack somewhere nobody
295 /// measured. SQLite refuses at depth 1000.
296 ///
297 /// It is charged here rather than inside `Ast::add_expr` because
298 /// `add_expr` is infallible and called from about a hundred places; this is
299 /// one call in the Pratt loop, which every expression node passes through,
300 /// so a chain is refused after the term that crossed the limit rather than
301 /// after the whole statement is built.
302 fn charge_expr_depth(&mut self) -> Result<(), ParseError> {
303 if i64::from(self.ast.max_expr_depth()) > self.limits.get(Limit::ExprDepth) {
304 let span = Span::at(self.cursor());
305 return Err(ParseError::new(
306 ParseErrorKind::LimitExceeded("expression tree depth"),
307 span,
308 ));
309 }
310 // **The identifier count, charged at the same place and for the same
311 // reason.** `Ast::intern` is a hash lookup as of task-1932 and no
312 // longer quadratic, but a statement can still name arbitrarily many
313 // distinct identifiers under the `SqlLength` default, and every one of
314 // them is a `Name` holding two copies of its text. `Limit::Column` is
315 // the closest declared bound and this is deliberately generous against
316 // it - a name is a column, a table, an alias, a function or a
317 // collation, so one honest statement interns several times as many
318 // names as any one table has columns.
319 let names = i64::try_from(self.ast.name_count()).unwrap_or(i64::MAX);
320 if names > self.limits.get(Limit::Column).saturating_mul(64) {
321 let span = Span::at(self.cursor());
322 return Err(ParseError::new(
323 ParseErrorKind::LimitExceeded("distinct identifiers"),
324 span,
325 ));
326 }
327 Ok(())
328 }
329
330 /// Returns whether a token may be read as a name here.
331 ///
332 /// A quoted word is always a name. A bare word is a name unless it is a
333 /// hard keyword, where "hard" is [`Keyword::may_be_name`] - SQLite's
334 /// `nm ::= idj | STRING` with `idj ::= ID|INDEXED|JOIN_KW`, so the fallback
335 /// set plus the seven join keywords plus `INDEXED`. This is the
336 /// per-position question SQLite's grammar asks, asked in the one place that
337 /// can answer it.
338 ///
339 /// It used to ask [`Keyword::may_fall_back`], which is the
340 /// narrower of the two sets and made `CREATE TABLE pairs (left TEXT)` - a
341 /// schema SQLite itself writes - a syntax error.
342 fn token_is_name(token: Token) -> bool {
343 match token.kind {
344 TokenKind::Identifier { keyword, quote } => match quote {
345 QuoteForm::Bare => keyword.is_none_or(Keyword::may_be_name),
346 _ => true,
347 },
348 _ => false,
349 }
350 }
351
352 /// Returns whether a token may be read where SQLite's grammar writes `ids`.
353 ///
354 /// `%token_class ids ID|STRING` - deliberately narrower than
355 /// [`Parser::token_is_name`], which is the `idj` class and takes the join
356 /// keywords and `INDEXED` as well. **Two** positions in the grammar take
357 /// the narrow class and both were measured against the pinned release:
358 ///
359 /// - a bare alias, `as ::= ids`. This is what stops a join keyword being
360 /// eaten as the alias of the table before it: `SELECT * FROM t LEFT JOIN
361 /// u` is a join and `SELECT a left FROM t` is a syntax error, in SQLite
362 /// and here. The same rule leaves `INDEXED` for `INDEXED BY` to claim.
363 /// - a declared type, `typename ::= ids`. `CREATE TABLE t (a left)` is a
364 /// syntax error in SQLite even though `CREATE TABLE t (left a)` is not,
365 /// because the name position and the type position take different
366 /// classes. `CREATE TABLE t (a key)` parses, because `KEY` is in the
367 /// fallback set and so lexes as `ID`.
368 fn token_is_plain_name(token: Token) -> bool {
369 match token.kind {
370 TokenKind::Identifier { keyword, quote } => match quote {
371 QuoteForm::Bare => keyword.is_none_or(Keyword::may_fall_back),
372 _ => true,
373 },
374 _ => false,
375 }
376 }
377
378 /// Reports whether a token is a word, keyword or not.
379 ///
380 /// It is deliberately weaker than [`Parser::token_is_name`], which asks
381 /// whether a word may stand where an identifier is expected. Some
382 /// positions - a pragma's value is the one - accept the spelling of a
383 /// reserved word because nothing else can appear there.
384 fn token_is_word(token: Token) -> bool {
385 matches!(token.kind, TokenKind::Identifier { .. })
386 }
387
388 /// Returns whether the next token may be read as a name.
389 fn at_name(&mut self) -> Result<bool, ParseError> {
390 Ok(Parser::token_is_name(self.peek()?))
391 }
392
393 /// Returns whether the next token may be read where the grammar writes
394 /// `ids` - a bare alias, or a declared type name.
395 fn at_plain_name(&mut self) -> Result<bool, ParseError> {
396 Ok(Parser::token_is_plain_name(self.peek()?))
397 }
398
399 /// Refuses a subquery where SQLite refuses one.
400 ///
401 /// `CHECK (a IN (SELECT ...))` is `subqueries prohibited in CHECK
402 /// constraints` in SQLite and was **accepted** here - a constraint that
403 /// would be evaluated per row against a query, which this engine has no
404 /// intention of doing, so the declaration was being stored and not
405 /// enforced. That is the shape of failure the whole `CHECK` work exists to
406 /// avoid: a declaration the application trusts, doing nothing.
407 ///
408 /// @param before - the `SELECT` count taken before the expression
409 /// @param span - where the constraint was written
410 fn no_subquery_in_check(&mut self, before: u64, span: Span) -> Result<(), ParseError> {
411 if self.selects == before {
412 return Ok(());
413 }
414 Err(ParseError::new(
415 ParseErrorKind::Refused("subqueries prohibited in CHECK constraints".to_string()),
416 span,
417 ))
418 }
419
420 /// Consumes an identifier, interning it.
421 fn parse_name(&mut self) -> Result<NameId, ParseError> {
422 Ok(self.parse_name_spanned()?.0)
423 }
424
425 /// Parses an identifier and returns where it was written.
426 ///
427 /// The written position and the interned name's position are not the same
428 /// thing, and confusing them is a real bug rather than a cosmetic one.
429 /// Interning deduplicates, so the name `b` in `CHECK (b > 0)` resolves to
430 /// the entry the *column declaration* `b INTEGER` created, and that entry
431 /// carries the declaration's span. Building the expression's span from it
432 /// made `CHECK (b > 0)` claim to span `b INTEGER CHECK (b > 0`, which the
433 /// catalog then stored as the constraint's source and could not reparse.
434 /// The token's own span is the only one that describes this occurrence.
435 fn parse_name_spanned(&mut self) -> Result<(NameId, Span), ParseError> {
436 let token = self.peek()?;
437 // **A string literal where a name is required is a name.** SQLite's own
438 // documented misfeature, and not an academic one: SQLite *writes*
439 // `CREATE TABLE 'f_data'(id INTEGER PRIMARY KEY, block BLOB)` into
440 // `sqlite_schema` for an FTS5 table's shadow storage, so a migration
441 // that could not read it reported "the declaration of f_data did not
442 // parse: database disk image is malformed" about a perfectly good file.
443 //
444 // Only here, where the grammar *requires* a name - the lookahead
445 // `at_name` is deliberately left alone, so nothing about which
446 // alternative the parser takes changes. Accepting a string in a
447 // required position can only turn a parse error into a parse.
448 if !Parser::token_is_name(token) && token.kind != TokenKind::String {
449 return Err(self.unexpected(&["a name"])?);
450 }
451 self.bump()?;
452 Ok((self.intern_token(token), token.span))
453 }
454
455 /// Interns an identifier token into the arena.
456 ///
457 /// **The `Cow` is passed on rather than owned (task-2039).** Both of these
458 /// borrow the source for a bare word, which is nearly every identifier in
459 /// nearly every statement; `into_owned` copied it anyway so that
460 /// `Ast::intern` would have a `Vec<u8>` to take, and a name the arena had
461 /// already interned - the same column written twice - paid for that copy
462 /// and threw it away. `Ast::intern_bytes` looks the name up from the bytes
463 /// where they are.
464 fn intern_token(&mut self, token: Token) -> NameId {
465 // A string standing in for a name is interned as the name it spells,
466 // with its own quoting undone - and remembered as double-quoted, which
467 // is how it is written back out when the declaration is rendered.
468 if token.kind == TokenKind::String {
469 let text = lexer::string_text(self.source, token);
470 return self.ast.intern_bytes(&text, QuoteForm::Double, token.span);
471 }
472 let quote = match token.kind {
473 TokenKind::Identifier { quote, .. } => quote,
474 _ => QuoteForm::Bare,
475 };
476 let text = lexer::identifier_text(self.source, token);
477 self.ast.intern_bytes(&text, quote, token.span)
478 }
479
480 /// Parses an optional `schema.` qualifier followed by a name.
481 ///
482 /// Returns the qualifier and the name. The lookahead is what distinguishes
483 /// `main.t` from a column reference; the dot has to be there *and* be
484 /// followed by a name for the first word to be a qualifier.
485 fn parse_qualified_name(&mut self) -> Result<(Option<NameId>, NameId), ParseError> {
486 let (database, name, _) = self.parse_qualified_name_spanned()?;
487 Ok((database, name))
488 }
489
490 /// Parses `name` or `database.name` and returns where the last part was
491 /// written.
492 ///
493 /// The written span is the token's, for the reason
494 /// [`Parser::parse_name_spanned`] gives: interning deduplicates, so the
495 /// interned entry's span belongs to whichever occurrence was seen first.
496 fn parse_qualified_name_spanned(
497 &mut self,
498 ) -> Result<(Option<NameId>, NameId, Span), ParseError> {
499 let (first, written) = self.parse_name_spanned()?;
500 if self.at(Punctuator::Dot)? && Parser::token_is_name(self.peek_at(1)?) {
501 self.bump()?;
502 let (second, written) = self.parse_name_spanned()?;
503 return Ok((Some(first), second, written));
504 }
505 Ok((None, first, written))
506 }
507
508 /// Parses an optional `AS alias` or bare alias.
509 fn parse_alias(&mut self) -> Result<(Option<NameId>, bool), ParseError> {
510 if self.eat_keyword(Keyword::AS)? {
511 let name = self.parse_name()?;
512 return Ok((Some(name), true));
513 }
514 // A bare alias is any word in the *fallback* set - not the wider name
515 // set, which would read the `LEFT` of `FROM t LEFT JOIN u` as an alias
516 // and the `INDEXED` of `FROM t INDEXED BY i` as one too. SQLite draws
517 // the same line, in the same place, for the same reason.
518 //
519 // `WINDOW` needs one more exception on top of that: it *is* in the
520 // fallback set, so `FROM t WINDOW w AS (...)` would read `WINDOW` as
521 // the table's alias and then choke on `w`. SQLite's own grammar gives
522 // it the same special treatment.
523 if self.at_keyword(Keyword::WINDOW)? {
524 return Ok((None, false));
525 }
526 if Parser::token_is_plain_name(self.peek()?) {
527 let name = self.parse_name()?;
528 return Ok((Some(name), false));
529 }
530 Ok((None, false))
531 }
532
533 /// Records a parameter and returns the index it was assigned.
534 ///
535 /// SQLite's rule is that a bare `?` takes one past the highest index used
536 /// so far, an explicit `?NNN` takes exactly NNN and raises the high-water
537 /// mark, and a repeated `:name` reuses the index the first occurrence got.
538 fn assign_parameter(&mut self, token: Token) -> Result<(u32, Option<NameId>), ParseError> {
539 let text = token.text(self.source);
540 let sigil = text.first().copied().unwrap_or(b'?');
541 let limit = self.limits.get(Limit::VariableNumber).max(0) as u32;
542 if sigil == b'?' && text.len() > 1 {
543 let digits = text.get(1..).unwrap_or(&[]);
544 let mut index: u32 = 0;
545 for byte in digits {
546 index = index
547 .saturating_mul(10)
548 .saturating_add(u32::from(byte.saturating_sub(b'0')));
549 }
550 if index == 0 || index > limit {
551 return Err(ParseError::new(
552 ParseErrorKind::LimitExceeded("variable number"),
553 token.span,
554 ));
555 }
556 self.parameters.count = self.parameters.count.max(index);
557 return Ok((index, None));
558 }
559 if sigil == b'?' {
560 let index = self.parameters.count.saturating_add(1);
561 if index > limit {
562 return Err(ParseError::new(
563 ParseErrorKind::LimitExceeded("variable number"),
564 token.span,
565 ));
566 }
567 self.parameters.count = index;
568 return Ok((index, None));
569 }
570 // The named forms only. `text` borrows the source, so a `:name` seen a
571 // second time costs nothing at all now: it used to copy the name to
572 // look the index up with, and copy it again for `intern` to take.
573 if let Some(index) = self.parameters.index_of(text) {
574 let id = self.ast.intern_bytes(text, QuoteForm::Bare, token.span);
575 return Ok((index, Some(id)));
576 }
577 let index = self.parameters.count.saturating_add(1);
578 if index > limit {
579 return Err(ParseError::new(
580 ParseErrorKind::LimitExceeded("variable number"),
581 token.span,
582 ));
583 }
584 self.parameters.count = index;
585 self.parameters.names.push((text.to_vec(), index));
586 let id = self.ast.intern_bytes(text, QuoteForm::Bare, token.span);
587 Ok((index, Some(id)))
588 }
589
590 /// Parses one statement, without the `EXPLAIN` prefix or the terminator.
591 fn parse_statement(&mut self) -> Result<Statement, ParseError> {
592 self.enter()?;
593 let parsed = self.parse_statement_inner();
594 self.leave();
595 parsed
596 }
597
598 /// Dispatches on the leading keyword.
599 fn parse_statement_inner(&mut self) -> Result<Statement, ParseError> {
600 let token = self.peek()?;
601 if token.kind == TokenKind::EndOfInput {
602 return Ok(Statement::Empty);
603 }
604 if token.is(Punctuator::Semicolon) {
605 return Ok(Statement::Empty);
606 }
607 let Some(keyword) = token.keyword() else {
608 return Err(self.unexpected(&["a statement"])?);
609 };
610 match keyword {
611 Keyword::EXPLAIN => self.parse_explain(),
612 Keyword::WITH => self.parse_after_with(),
613 Keyword::SELECT | Keyword::VALUES => self.parse_select_statement(),
614 Keyword::INSERT | Keyword::REPLACE => self.parse_insert(),
615 Keyword::UPDATE => self.parse_update(),
616 Keyword::DELETE => self.parse_delete(),
617 Keyword::CREATE => self.parse_create(),
618 Keyword::DROP => self.parse_drop(),
619 Keyword::ALTER => self.parse_alter(),
620 Keyword::BEGIN => self.parse_begin(),
621 Keyword::COMMIT | Keyword::END => self.parse_commit(),
622 Keyword::ROLLBACK => self.parse_rollback(),
623 Keyword::SAVEPOINT => self.parse_savepoint(),
624 Keyword::RELEASE => self.parse_release(),
625 Keyword::PRAGMA => self.parse_pragma(),
626 Keyword::ATTACH => self.parse_attach(),
627 Keyword::DETACH => self.parse_detach(),
628 Keyword::VACUUM => self.parse_vacuum(),
629 Keyword::ANALYZE => self.parse_analyze(),
630 Keyword::REINDEX => self.parse_reindex(),
631 _ => Err(self.unexpected(&["a statement"])?),
632 }
633 }
634
635 /// Dispatches a statement that begins with a `WITH` prefix.
636 ///
637 /// The prefix does not say what follows it: `WITH c AS (...)` may lead to a
638 /// SELECT, an INSERT, an UPDATE or a DELETE, and the CTE bodies in between
639 /// contain SELECTs of their own. The scan therefore counts parentheses and
640 /// takes the first statement keyword at depth zero; taking the first one at
641 /// any depth reads `WITH c AS (SELECT 1) DELETE FROM t` as a query.
642 fn parse_after_with(&mut self) -> Result<Statement, ParseError> {
643 let mut ahead = 1usize;
644 let mut depth = 0usize;
645 loop {
646 let token = self.peek_at(ahead)?;
647 match token.kind {
648 TokenKind::EndOfInput => return Err(self.unexpected(&["a statement"])?),
649 TokenKind::Punctuator(Punctuator::LeftParen) => depth = depth.saturating_add(1),
650 TokenKind::Punctuator(Punctuator::RightParen) => depth = depth.saturating_sub(1),
651 _ if depth == 0 => match token.keyword() {
652 Some(Keyword::SELECT) | Some(Keyword::VALUES) => {
653 return self.parse_select_statement()
654 }
655 Some(Keyword::INSERT) | Some(Keyword::REPLACE) => return self.parse_insert(),
656 Some(Keyword::UPDATE) => return self.parse_update(),
657 Some(Keyword::DELETE) => return self.parse_delete(),
658 _ => {}
659 },
660 _ => {}
661 }
662 ahead = ahead.saturating_add(1);
663 }
664 }
665
666 /// Parses `EXPLAIN [QUERY PLAN] <statement>`.
667 fn parse_explain(&mut self) -> Result<Statement, ParseError> {
668 self.expect_keyword(Keyword::EXPLAIN)?;
669 let query_plan = if self.at_keyword(Keyword::QUERY)? {
670 self.bump()?;
671 self.expect_keyword(Keyword::PLAN)?;
672 true
673 } else {
674 false
675 };
676 let inner = self.parse_statement()?;
677 if inner == Statement::Empty {
678 // `EXPLAIN;` is not a statement with nothing in it, it is a missing
679 // statement, and SQLite reports it as a syntax error.
680 return Err(self.unexpected(&["a statement to explain"])?);
681 }
682 Ok(Statement::Explain {
683 query_plan,
684 inner: Box::new(inner),
685 })
686 }
687
688 /// Parses `BEGIN [DEFERRED|IMMEDIATE|EXCLUSIVE] [TRANSACTION]`.
689 fn parse_begin(&mut self) -> Result<Statement, ParseError> {
690 use crate::ast::TransactionBehaviour;
691 self.expect_keyword(Keyword::BEGIN)?;
692 let behaviour = if self.eat_keyword(Keyword::DEFERRED)? {
693 Some(TransactionBehaviour::Deferred)
694 } else if self.eat_keyword(Keyword::IMMEDIATE)? {
695 Some(TransactionBehaviour::Immediate)
696 } else if self.eat_keyword(Keyword::EXCLUSIVE)? {
697 Some(TransactionBehaviour::Exclusive)
698 } else {
699 None
700 };
701 self.eat_keyword(Keyword::TRANSACTION)?;
702 Ok(Statement::Begin { behaviour })
703 }
704
705 /// Parses `COMMIT|END [TRANSACTION]`.
706 fn parse_commit(&mut self) -> Result<Statement, ParseError> {
707 self.bump()?;
708 self.eat_keyword(Keyword::TRANSACTION)?;
709 Ok(Statement::Commit)
710 }
711
712 /// Parses `ROLLBACK [TRANSACTION] [TO [SAVEPOINT] name]`.
713 fn parse_rollback(&mut self) -> Result<Statement, ParseError> {
714 self.expect_keyword(Keyword::ROLLBACK)?;
715 self.eat_keyword(Keyword::TRANSACTION)?;
716 if self.eat_keyword(Keyword::TO)? {
717 self.eat_keyword(Keyword::SAVEPOINT)?;
718 let name = self.parse_name()?;
719 return Ok(Statement::Rollback {
720 savepoint: Some(name),
721 });
722 }
723 Ok(Statement::Rollback { savepoint: None })
724 }
725
726 /// Parses `SAVEPOINT name`.
727 fn parse_savepoint(&mut self) -> Result<Statement, ParseError> {
728 self.expect_keyword(Keyword::SAVEPOINT)?;
729 Ok(Statement::Savepoint(self.parse_name()?))
730 }
731
732 /// Parses `RELEASE [SAVEPOINT] name`.
733 fn parse_release(&mut self) -> Result<Statement, ParseError> {
734 self.expect_keyword(Keyword::RELEASE)?;
735 self.eat_keyword(Keyword::SAVEPOINT)?;
736 Ok(Statement::Release(self.parse_name()?))
737 }
738
739 /// Parses `PRAGMA [schema.]name [= value | (value)]`.
740 fn parse_pragma(&mut self) -> Result<Statement, ParseError> {
741 use crate::ast::PragmaValue;
742 self.expect_keyword(Keyword::PRAGMA)?;
743 let (database, name) = self.parse_qualified_name()?;
744 let value = if self.eat(Punctuator::Equal)? {
745 PragmaValue::Value(self.parse_pragma_value()?)
746 } else if self.eat(Punctuator::LeftParen)? {
747 let value = if self.at_name()? && self.peek_at(1)?.is(Punctuator::RightParen) {
748 PragmaValue::Name(self.parse_name()?)
749 } else {
750 PragmaValue::Value(self.parse_pragma_value()?)
751 };
752 self.expect(Punctuator::RightParen)?;
753 value
754 } else {
755 PragmaValue::None
756 };
757 Ok(Statement::Pragma {
758 database,
759 name,
760 value,
761 })
762 }
763
764 /// Parses the value half of a PRAGMA, which is a signed literal or a word.
765 ///
766 /// Any word is a word here, keyword or not. `PRAGMA journal_mode=DELETE`
767 /// names a mode, not the statement, and the same is true of `=FULL`,
768 /// `=TRUNCATE`, `=ON` and `=OFF` - there is nothing in this position that
769 /// could be a column, so there is nothing for a reserved word to shadow.
770 fn parse_pragma_value(&mut self) -> Result<crate::ast::ExprId, ParseError> {
771 use crate::ast::{Expr, Literal};
772 let token = self.peek()?;
773 if Parser::token_is_word(token) && !self.peek_at(1)?.is(Punctuator::LeftParen) {
774 self.bump()?;
775 let text = lexer::identifier_text(self.source, token).into_owned();
776 return Ok(self
777 .ast
778 .add_expr(Expr::Literal(Literal::String(text)), token.span));
779 }
780 self.parse_expr()
781 }
782
783 /// Parses `ATTACH [DATABASE] file AS schema [KEY key]`.
784 fn parse_attach(&mut self) -> Result<Statement, ParseError> {
785 self.expect_keyword(Keyword::ATTACH)?;
786 self.eat_keyword(Keyword::DATABASE)?;
787 let file = self.parse_expr()?;
788 self.expect_keyword(Keyword::AS)?;
789 let schema = self.parse_expr()?;
790 let key = if self.eat_keyword(Keyword::KEY)? {
791 Some(self.parse_expr()?)
792 } else {
793 None
794 };
795 Ok(Statement::Attach { file, schema, key })
796 }
797
798 /// Parses `DETACH [DATABASE] schema`.
799 fn parse_detach(&mut self) -> Result<Statement, ParseError> {
800 self.expect_keyword(Keyword::DETACH)?;
801 self.eat_keyword(Keyword::DATABASE)?;
802 Ok(Statement::Detach {
803 schema: self.parse_expr()?,
804 })
805 }
806
807 /// Parses `VACUUM [schema] [INTO file]`.
808 fn parse_vacuum(&mut self) -> Result<Statement, ParseError> {
809 self.expect_keyword(Keyword::VACUUM)?;
810 let database = if self.at_name()? && !self.at_keyword(Keyword::INTO)? {
811 Some(self.parse_name()?)
812 } else {
813 None
814 };
815 let into = if self.eat_keyword(Keyword::INTO)? {
816 Some(self.parse_expr()?)
817 } else {
818 None
819 };
820 Ok(Statement::Vacuum { database, into })
821 }
822
823 /// Parses `ANALYZE [[schema.]name]`.
824 fn parse_analyze(&mut self) -> Result<Statement, ParseError> {
825 self.expect_keyword(Keyword::ANALYZE)?;
826 if !self.at_name()? {
827 return Ok(Statement::Analyze {
828 database: None,
829 name: None,
830 });
831 }
832 let (database, name) = self.parse_qualified_name()?;
833 Ok(Statement::Analyze {
834 database,
835 name: Some(name),
836 })
837 }
838
839 /// Parses `REINDEX [[schema.]name]`.
840 fn parse_reindex(&mut self) -> Result<Statement, ParseError> {
841 self.expect_keyword(Keyword::REINDEX)?;
842 if !self.at_name()? {
843 return Ok(Statement::Reindex {
844 database: None,
845 name: None,
846 });
847 }
848 let (database, name) = self.parse_qualified_name()?;
849 Ok(Statement::Reindex {
850 database,
851 name: Some(name),
852 })
853 }
854}
855
856/// Parses the next statement beginning at `offset`.
857///
858/// The returned `consumed` count is what a caller advances by to reach the
859/// tail, which is SQLite's prepare contract. A source that holds only trivia
860/// yields an empty statement and consumes all of it.
861pub fn parse_next_statement(
862 source: &[u8],
863 offset: usize,
864 limits: &Limits,
865) -> Result<ParsedStatement, ParseError> {
866 parse_next_statement_into(source, offset, limits, Ast::new())
867}
868
869/// Parses one statement into an arena the caller supplies.
870///
871/// The same parse as [`parse_next_statement`], with the arena handed in rather
872/// than made. A caller that compiles statement after statement keeps one and
873/// gets its capacity back on every parse after the first, which on `SELECT 1`
874/// is most of what a parse costs.
875///
876/// @param source - the SQL text
877/// @param offset - where in it this statement starts
878/// @param limits - the limits to enforce
879/// @param arena - the arena to fill, cleared first
880pub fn parse_next_statement_into(
881 source: &[u8],
882 offset: usize,
883 limits: &Limits,
884 arena: Ast,
885) -> Result<ParsedStatement, ParseError> {
886 let length = source.len().saturating_sub(offset) as i64;
887 if length > limits.get(Limit::SqlLength) {
888 return Err(ParseError::new(
889 ParseErrorKind::LimitExceeded("SQL statement length"),
890 Span::at(offset),
891 ));
892 }
893 let mut parser = Parser::with_arena(source, offset, limits, arena);
894 let start = parser.cursor();
895 let statement = parser.parse_statement()?;
896 let end = parser.cursor();
897 // Everything up to and including the terminator belongs to this statement;
898 // what follows is the caller's tail.
899 let token = parser.peek()?;
900 let consumed = match token.kind {
901 TokenKind::EndOfInput => source.len(),
902 TokenKind::Punctuator(Punctuator::Semicolon) => {
903 parser.bump()?;
904 token.span.end as usize
905 }
906 _ => return Err(parser.unexpected(&[";"])?),
907 };
908 let span = Span::new(start, end);
909 // Taken rather than cloned: the parser is about to be consumed, so the map
910 // it built is the caller's and copying it is a `Vec` per parse for nothing.
911 let parameters = core::mem::take(&mut parser.parameters);
912 Ok(ParsedStatement {
913 ast: parser.into_ast(),
914 statement,
915 consumed,
916 parameters,
917 span,
918 })
919}
920
921/// Parses a bare expression, which is what a CHECK constraint or a default
922/// value is when it is re-read out of `sqlite_schema`.
923pub fn parse_expression(
924 source: &[u8],
925 limits: &Limits,
926) -> Result<(Ast, crate::ast::ExprId), ParseError> {
927 let mut parser = Parser::new(source, 0, limits);
928 let expr = parser.parse_expr()?;
929 let token = parser.peek()?;
930 if token.kind != TokenKind::EndOfInput {
931 return Err(parser.unexpected(&["end of expression"])?);
932 }
933 Ok((parser.into_ast(), expr))
934}
935
936/// Classifies a statement from its leading keywords alone.
937///
938/// This is what a caller uses to decide whether a statement may run on a
939/// read-only connection without paying for a parse.
940pub fn classify_statement(source: &[u8]) -> StatementClass {
941 let mut lexer = Lexer::new(source);
942 let first = match lexer.next_token() {
943 Ok(token) => token,
944 Err(_) => return StatementClass::Unknown,
945 };
946 if first.keyword() == Some(Keyword::EXPLAIN) {
947 // EXPLAIN never runs the statement, so it is always read-only, but the
948 // caller may still want to know what it wraps.
949 return StatementClass::ReadOnly;
950 }
951 if first.kind == TokenKind::EndOfInput
952 || first.kind == TokenKind::Punctuator(Punctuator::Semicolon)
953 {
954 return StatementClass::Empty;
955 }
956 if first.keyword() == Some(Keyword::WITH) {
957 // A WITH prefix may lead to any of SELECT, INSERT, UPDATE or DELETE.
958 // The CTE bodies in between are full SELECTs, so the scan has to count
959 // parentheses and only believe a keyword at depth zero.
960 let mut depth = 0usize;
961 loop {
962 let token = match lexer.next_token() {
963 Ok(token) => token,
964 Err(_) => return StatementClass::Unknown,
965 };
966 match token.kind {
967 TokenKind::EndOfInput => return StatementClass::Unknown,
968 TokenKind::Punctuator(Punctuator::LeftParen) => {
969 depth = depth.saturating_add(1);
970 continue;
971 }
972 TokenKind::Punctuator(Punctuator::RightParen) => {
973 depth = depth.saturating_sub(1);
974 continue;
975 }
976 _ => {}
977 }
978 if depth != 0 {
979 continue;
980 }
981 match token.keyword() {
982 Some(Keyword::SELECT) | Some(Keyword::VALUES) => return StatementClass::ReadOnly,
983 Some(Keyword::INSERT) | Some(Keyword::UPDATE) | Some(Keyword::DELETE) => {
984 return StatementClass::Write
985 }
986 _ => {}
987 }
988 }
989 }
990 match first.keyword() {
991 Some(Keyword::SELECT) | Some(Keyword::VALUES) => StatementClass::ReadOnly,
992 Some(Keyword::INSERT)
993 | Some(Keyword::REPLACE)
994 | Some(Keyword::UPDATE)
995 | Some(Keyword::DELETE) => StatementClass::Write,
996 Some(Keyword::CREATE)
997 | Some(Keyword::DROP)
998 | Some(Keyword::ALTER)
999 | Some(Keyword::REINDEX)
1000 | Some(Keyword::ANALYZE)
1001 | Some(Keyword::VACUUM) => StatementClass::SchemaChange,
1002 Some(Keyword::BEGIN)
1003 | Some(Keyword::COMMIT)
1004 | Some(Keyword::END)
1005 | Some(Keyword::ROLLBACK)
1006 | Some(Keyword::SAVEPOINT)
1007 | Some(Keyword::RELEASE) => StatementClass::TransactionControl,
1008 Some(Keyword::PRAGMA) => StatementClass::Pragma,
1009 Some(Keyword::ATTACH) | Some(Keyword::DETACH) => StatementClass::SchemaChange,
1010 _ => StatementClass::Unknown,
1011 }
1012}