Skip to main content

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}