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    ///
539    /// `$N`, a `$` followed only by digits, is the one place this engine
540    /// departs from SQLite. SQLite treats `$1` as a name and numbers it by the
541    /// order names first appear, so `SET a = $2 WHERE id = $1` binds the first
542    /// value to `$2`. Code written for PostgreSQL means `$N` as the Nth value,
543    /// and under SQLite's rule it ran without an error and changed the wrong
544    /// rows. So `$N` takes index N, exactly as `?N` does, and keeps its name so
545    /// a caller that looks `$1` up by name still finds index 1.
546    fn assign_parameter(&mut self, token: Token) -> Result<(u32, Option<NameId>), ParseError> {
547        let text = token.text(self.source);
548        let sigil = text.first().copied().unwrap_or(b'?');
549        let limit = self.limits.get(Limit::VariableNumber).max(0) as u32;
550        let numbered_dollar = sigil == b'$'
551            && text.len() > 1
552            && text
553                .get(1..)
554                .is_some_and(|rest| rest.iter().all(u8::is_ascii_digit));
555        if numbered_dollar {
556            return self.assign_numbered_dollar(token, text, limit);
557        }
558        if sigil == b'?' && text.len() > 1 {
559            let digits = text.get(1..).unwrap_or(&[]);
560            let mut index: u32 = 0;
561            for byte in digits {
562                index = index
563                    .saturating_mul(10)
564                    .saturating_add(u32::from(byte.saturating_sub(b'0')));
565            }
566            if index == 0 || index > limit {
567                return Err(ParseError::new(
568                    ParseErrorKind::LimitExceeded("variable number"),
569                    token.span,
570                ));
571            }
572            self.parameters.count = self.parameters.count.max(index);
573            return Ok((index, None));
574        }
575        if sigil == b'?' {
576            let index = self.parameters.count.saturating_add(1);
577            if index > limit {
578                return Err(ParseError::new(
579                    ParseErrorKind::LimitExceeded("variable number"),
580                    token.span,
581                ));
582            }
583            self.parameters.count = index;
584            return Ok((index, None));
585        }
586        // The named forms only. `text` borrows the source, so a `:name` seen a
587        // second time costs nothing at all now: it used to copy the name to
588        // look the index up with, and copy it again for `intern` to take.
589        if let Some(index) = self.parameters.index_of(text) {
590            let id = self.ast.intern_bytes(text, QuoteForm::Bare, token.span);
591            return Ok((index, Some(id)));
592        }
593        let index = self.parameters.count.saturating_add(1);
594        if index > limit {
595            return Err(ParseError::new(
596                ParseErrorKind::LimitExceeded("variable number"),
597                token.span,
598            ));
599        }
600        self.parameters.count = index;
601        self.parameters.names.push((text.to_vec(), index));
602        let id = self.ast.intern_bytes(text, QuoteForm::Bare, token.span);
603        Ok((index, Some(id)))
604    }
605
606    /// Records a `$N` parameter at index N, the PostgreSQL meaning.
607    ///
608    /// The name is recorded once with its own number, so a lookup of `$2` by
609    /// name answers 2 whether or not `$1` appeared first.
610    /// @param token - the `$N` token
611    /// @param text - the token's text, `$` and the digits
612    /// @param limit - the highest index the connection allows
613    fn assign_numbered_dollar(
614        &mut self,
615        token: Token,
616        text: &[u8],
617        limit: u32,
618    ) -> Result<(u32, Option<NameId>), ParseError> {
619        let mut index: u32 = 0;
620        for byte in text.get(1..).unwrap_or(&[]) {
621            index = index
622                .saturating_mul(10)
623                .saturating_add(u32::from(byte.saturating_sub(b'0')));
624        }
625        if index == 0 || index > limit {
626            return Err(ParseError::new(
627                ParseErrorKind::LimitExceeded("variable number"),
628                token.span,
629            ));
630        }
631        self.parameters.count = self.parameters.count.max(index);
632        if self.parameters.index_of(text).is_none() {
633            self.parameters.names.push((text.to_vec(), index));
634        }
635        let id = self.ast.intern_bytes(text, QuoteForm::Bare, token.span);
636        Ok((index, Some(id)))
637    }
638
639    /// Parses one statement, without the `EXPLAIN` prefix or the terminator.
640    fn parse_statement(&mut self) -> Result<Statement, ParseError> {
641        self.enter()?;
642        let parsed = self.parse_statement_inner();
643        self.leave();
644        parsed
645    }
646
647    /// Dispatches on the leading keyword.
648    fn parse_statement_inner(&mut self) -> Result<Statement, ParseError> {
649        let token = self.peek()?;
650        if token.kind == TokenKind::EndOfInput {
651            return Ok(Statement::Empty);
652        }
653        if token.is(Punctuator::Semicolon) {
654            return Ok(Statement::Empty);
655        }
656        let Some(keyword) = token.keyword() else {
657            return Err(self.unexpected(&["a statement"])?);
658        };
659        match keyword {
660            Keyword::EXPLAIN => self.parse_explain(),
661            Keyword::WITH => self.parse_after_with(),
662            Keyword::SELECT | Keyword::VALUES => self.parse_select_statement(),
663            Keyword::INSERT | Keyword::REPLACE => self.parse_insert(),
664            Keyword::UPDATE => self.parse_update(),
665            Keyword::DELETE => self.parse_delete(),
666            Keyword::CREATE => self.parse_create(),
667            Keyword::DROP => self.parse_drop(),
668            Keyword::ALTER => self.parse_alter(),
669            Keyword::BEGIN => self.parse_begin(),
670            Keyword::COMMIT | Keyword::END => self.parse_commit(),
671            Keyword::ROLLBACK => self.parse_rollback(),
672            Keyword::SAVEPOINT => self.parse_savepoint(),
673            Keyword::RELEASE => self.parse_release(),
674            Keyword::PRAGMA => self.parse_pragma(),
675            Keyword::ATTACH => self.parse_attach(),
676            Keyword::DETACH => self.parse_detach(),
677            Keyword::VACUUM => self.parse_vacuum(),
678            Keyword::ANALYZE => self.parse_analyze(),
679            Keyword::REINDEX => self.parse_reindex(),
680            _ => Err(self.unexpected(&["a statement"])?),
681        }
682    }
683
684    /// Dispatches a statement that begins with a `WITH` prefix.
685    ///
686    /// The prefix does not say what follows it: `WITH c AS (...)` may lead to a
687    /// SELECT, an INSERT, an UPDATE or a DELETE, and the CTE bodies in between
688    /// contain SELECTs of their own. The scan therefore counts parentheses and
689    /// takes the first statement keyword at depth zero; taking the first one at
690    /// any depth reads `WITH c AS (SELECT 1) DELETE FROM t` as a query.
691    fn parse_after_with(&mut self) -> Result<Statement, ParseError> {
692        let mut ahead = 1usize;
693        let mut depth = 0usize;
694        loop {
695            let token = self.peek_at(ahead)?;
696            match token.kind {
697                TokenKind::EndOfInput => return Err(self.unexpected(&["a statement"])?),
698                TokenKind::Punctuator(Punctuator::LeftParen) => depth = depth.saturating_add(1),
699                TokenKind::Punctuator(Punctuator::RightParen) => depth = depth.saturating_sub(1),
700                _ if depth == 0 => match token.keyword() {
701                    Some(Keyword::SELECT) | Some(Keyword::VALUES) => {
702                        return self.parse_select_statement()
703                    }
704                    Some(Keyword::INSERT) | Some(Keyword::REPLACE) => return self.parse_insert(),
705                    Some(Keyword::UPDATE) => return self.parse_update(),
706                    Some(Keyword::DELETE) => return self.parse_delete(),
707                    _ => {}
708                },
709                _ => {}
710            }
711            ahead = ahead.saturating_add(1);
712        }
713    }
714
715    /// Parses `EXPLAIN [QUERY PLAN] <statement>`.
716    fn parse_explain(&mut self) -> Result<Statement, ParseError> {
717        self.expect_keyword(Keyword::EXPLAIN)?;
718        let query_plan = if self.at_keyword(Keyword::QUERY)? {
719            self.bump()?;
720            self.expect_keyword(Keyword::PLAN)?;
721            true
722        } else {
723            false
724        };
725        let inner = self.parse_statement()?;
726        if inner == Statement::Empty {
727            // `EXPLAIN;` is not a statement with nothing in it, it is a missing
728            // statement, and SQLite reports it as a syntax error.
729            return Err(self.unexpected(&["a statement to explain"])?);
730        }
731        Ok(Statement::Explain {
732            query_plan,
733            inner: Box::new(inner),
734        })
735    }
736
737    /// Parses `BEGIN [DEFERRED|IMMEDIATE|EXCLUSIVE] [TRANSACTION]`.
738    fn parse_begin(&mut self) -> Result<Statement, ParseError> {
739        use crate::ast::TransactionBehaviour;
740        self.expect_keyword(Keyword::BEGIN)?;
741        let behaviour = if self.eat_keyword(Keyword::DEFERRED)? {
742            Some(TransactionBehaviour::Deferred)
743        } else if self.eat_keyword(Keyword::IMMEDIATE)? {
744            Some(TransactionBehaviour::Immediate)
745        } else if self.eat_keyword(Keyword::EXCLUSIVE)? {
746            Some(TransactionBehaviour::Exclusive)
747        } else {
748            None
749        };
750        self.eat_keyword(Keyword::TRANSACTION)?;
751        Ok(Statement::Begin { behaviour })
752    }
753
754    /// Parses `COMMIT|END [TRANSACTION]`.
755    fn parse_commit(&mut self) -> Result<Statement, ParseError> {
756        self.bump()?;
757        self.eat_keyword(Keyword::TRANSACTION)?;
758        Ok(Statement::Commit)
759    }
760
761    /// Parses `ROLLBACK [TRANSACTION] [TO [SAVEPOINT] name]`.
762    fn parse_rollback(&mut self) -> Result<Statement, ParseError> {
763        self.expect_keyword(Keyword::ROLLBACK)?;
764        self.eat_keyword(Keyword::TRANSACTION)?;
765        if self.eat_keyword(Keyword::TO)? {
766            self.eat_keyword(Keyword::SAVEPOINT)?;
767            let name = self.parse_name()?;
768            return Ok(Statement::Rollback {
769                savepoint: Some(name),
770            });
771        }
772        Ok(Statement::Rollback { savepoint: None })
773    }
774
775    /// Parses `SAVEPOINT name`.
776    fn parse_savepoint(&mut self) -> Result<Statement, ParseError> {
777        self.expect_keyword(Keyword::SAVEPOINT)?;
778        Ok(Statement::Savepoint(self.parse_name()?))
779    }
780
781    /// Parses `RELEASE [SAVEPOINT] name`.
782    fn parse_release(&mut self) -> Result<Statement, ParseError> {
783        self.expect_keyword(Keyword::RELEASE)?;
784        self.eat_keyword(Keyword::SAVEPOINT)?;
785        Ok(Statement::Release(self.parse_name()?))
786    }
787
788    /// Parses `PRAGMA [schema.]name [= value | (value)]`.
789    fn parse_pragma(&mut self) -> Result<Statement, ParseError> {
790        use crate::ast::PragmaValue;
791        self.expect_keyword(Keyword::PRAGMA)?;
792        let (database, name) = self.parse_qualified_name()?;
793        let value = if self.eat(Punctuator::Equal)? {
794            PragmaValue::Value(self.parse_pragma_value()?)
795        } else if self.eat(Punctuator::LeftParen)? {
796            let value = if self.at_name()? && self.peek_at(1)?.is(Punctuator::RightParen) {
797                PragmaValue::Name(self.parse_name()?)
798            } else {
799                PragmaValue::Value(self.parse_pragma_value()?)
800            };
801            self.expect(Punctuator::RightParen)?;
802            value
803        } else {
804            PragmaValue::None
805        };
806        Ok(Statement::Pragma {
807            database,
808            name,
809            value,
810        })
811    }
812
813    /// Parses the value half of a PRAGMA, which is a signed literal or a word.
814    ///
815    /// Any word is a word here, keyword or not. `PRAGMA journal_mode=DELETE`
816    /// names a mode, not the statement, and the same is true of `=FULL`,
817    /// `=TRUNCATE`, `=ON` and `=OFF` - there is nothing in this position that
818    /// could be a column, so there is nothing for a reserved word to shadow.
819    fn parse_pragma_value(&mut self) -> Result<crate::ast::ExprId, ParseError> {
820        use crate::ast::{Expr, Literal};
821        let token = self.peek()?;
822        if Parser::token_is_word(token) && !self.peek_at(1)?.is(Punctuator::LeftParen) {
823            self.bump()?;
824            let text = lexer::identifier_text(self.source, token).into_owned();
825            return Ok(self
826                .ast
827                .add_expr(Expr::Literal(Literal::String(text)), token.span));
828        }
829        self.parse_expr()
830    }
831
832    /// Parses `ATTACH [DATABASE] file AS schema [KEY key]`.
833    fn parse_attach(&mut self) -> Result<Statement, ParseError> {
834        self.expect_keyword(Keyword::ATTACH)?;
835        self.eat_keyword(Keyword::DATABASE)?;
836        let file = self.parse_expr()?;
837        self.expect_keyword(Keyword::AS)?;
838        let schema = self.parse_expr()?;
839        let key = if self.eat_keyword(Keyword::KEY)? {
840            Some(self.parse_expr()?)
841        } else {
842            None
843        };
844        Ok(Statement::Attach { file, schema, key })
845    }
846
847    /// Parses `DETACH [DATABASE] schema`.
848    fn parse_detach(&mut self) -> Result<Statement, ParseError> {
849        self.expect_keyword(Keyword::DETACH)?;
850        self.eat_keyword(Keyword::DATABASE)?;
851        Ok(Statement::Detach {
852            schema: self.parse_expr()?,
853        })
854    }
855
856    /// Parses `VACUUM [schema] [INTO file]`.
857    fn parse_vacuum(&mut self) -> Result<Statement, ParseError> {
858        self.expect_keyword(Keyword::VACUUM)?;
859        let database = if self.at_name()? && !self.at_keyword(Keyword::INTO)? {
860            Some(self.parse_name()?)
861        } else {
862            None
863        };
864        let into = if self.eat_keyword(Keyword::INTO)? {
865            Some(self.parse_expr()?)
866        } else {
867            None
868        };
869        Ok(Statement::Vacuum { database, into })
870    }
871
872    /// Parses `ANALYZE [[schema.]name]`.
873    fn parse_analyze(&mut self) -> Result<Statement, ParseError> {
874        self.expect_keyword(Keyword::ANALYZE)?;
875        if !self.at_name()? {
876            return Ok(Statement::Analyze {
877                database: None,
878                name: None,
879            });
880        }
881        let (database, name) = self.parse_qualified_name()?;
882        Ok(Statement::Analyze {
883            database,
884            name: Some(name),
885        })
886    }
887
888    /// Parses `REINDEX [[schema.]name]`.
889    fn parse_reindex(&mut self) -> Result<Statement, ParseError> {
890        self.expect_keyword(Keyword::REINDEX)?;
891        if !self.at_name()? {
892            return Ok(Statement::Reindex {
893                database: None,
894                name: None,
895            });
896        }
897        let (database, name) = self.parse_qualified_name()?;
898        Ok(Statement::Reindex {
899            database,
900            name: Some(name),
901        })
902    }
903}
904
905/// Parses the next statement beginning at `offset`.
906///
907/// The returned `consumed` count is what a caller advances by to reach the
908/// tail, which is SQLite's prepare contract. A source that holds only trivia
909/// yields an empty statement and consumes all of it.
910pub fn parse_next_statement(
911    source: &[u8],
912    offset: usize,
913    limits: &Limits,
914) -> Result<ParsedStatement, ParseError> {
915    parse_next_statement_into(source, offset, limits, Ast::new())
916}
917
918/// Parses one statement into an arena the caller supplies.
919///
920/// The same parse as [`parse_next_statement`], with the arena handed in rather
921/// than made. A caller that compiles statement after statement keeps one and
922/// gets its capacity back on every parse after the first, which on `SELECT 1`
923/// is most of what a parse costs.
924///
925/// @param source - the SQL text
926/// @param offset - where in it this statement starts
927/// @param limits - the limits to enforce
928/// @param arena - the arena to fill, cleared first
929pub fn parse_next_statement_into(
930    source: &[u8],
931    offset: usize,
932    limits: &Limits,
933    arena: Ast,
934) -> Result<ParsedStatement, ParseError> {
935    let length = source.len().saturating_sub(offset) as i64;
936    if length > limits.get(Limit::SqlLength) {
937        return Err(ParseError::new(
938            ParseErrorKind::LimitExceeded("SQL statement length"),
939            Span::at(offset),
940        ));
941    }
942    let mut parser = Parser::with_arena(source, offset, limits, arena);
943    let start = parser.cursor();
944    let statement = parser.parse_statement()?;
945    let end = parser.cursor();
946    // Everything up to and including the terminator belongs to this statement;
947    // what follows is the caller's tail.
948    let token = parser.peek()?;
949    let consumed = match token.kind {
950        TokenKind::EndOfInput => source.len(),
951        TokenKind::Punctuator(Punctuator::Semicolon) => {
952            parser.bump()?;
953            token.span.end as usize
954        }
955        _ => return Err(parser.unexpected(&[";"])?),
956    };
957    let span = Span::new(start, end);
958    // Taken rather than cloned: the parser is about to be consumed, so the map
959    // it built is the caller's and copying it is a `Vec` per parse for nothing.
960    let parameters = core::mem::take(&mut parser.parameters);
961    Ok(ParsedStatement {
962        ast: parser.into_ast(),
963        statement,
964        consumed,
965        parameters,
966        span,
967    })
968}
969
970/// Parses a bare expression, which is what a CHECK constraint or a default
971/// value is when it is re-read out of `sqlite_schema`.
972pub fn parse_expression(
973    source: &[u8],
974    limits: &Limits,
975) -> Result<(Ast, crate::ast::ExprId), ParseError> {
976    let mut parser = Parser::new(source, 0, limits);
977    let expr = parser.parse_expr()?;
978    let token = parser.peek()?;
979    if token.kind != TokenKind::EndOfInput {
980        return Err(parser.unexpected(&["end of expression"])?);
981    }
982    Ok((parser.into_ast(), expr))
983}
984
985/// Classifies a statement from its leading keywords alone.
986///
987/// This is what a caller uses to decide whether a statement may run on a
988/// read-only connection without paying for a parse.
989pub fn classify_statement(source: &[u8]) -> StatementClass {
990    let mut lexer = Lexer::new(source);
991    let first = match lexer.next_token() {
992        Ok(token) => token,
993        Err(_) => return StatementClass::Unknown,
994    };
995    if first.keyword() == Some(Keyword::EXPLAIN) {
996        // EXPLAIN never runs the statement, so it is always read-only, but the
997        // caller may still want to know what it wraps.
998        return StatementClass::ReadOnly;
999    }
1000    if first.kind == TokenKind::EndOfInput
1001        || first.kind == TokenKind::Punctuator(Punctuator::Semicolon)
1002    {
1003        return StatementClass::Empty;
1004    }
1005    if first.keyword() == Some(Keyword::WITH) {
1006        // A WITH prefix may lead to any of SELECT, INSERT, UPDATE or DELETE.
1007        // The CTE bodies in between are full SELECTs, so the scan has to count
1008        // parentheses and only believe a keyword at depth zero.
1009        let mut depth = 0usize;
1010        loop {
1011            let token = match lexer.next_token() {
1012                Ok(token) => token,
1013                Err(_) => return StatementClass::Unknown,
1014            };
1015            match token.kind {
1016                TokenKind::EndOfInput => return StatementClass::Unknown,
1017                TokenKind::Punctuator(Punctuator::LeftParen) => {
1018                    depth = depth.saturating_add(1);
1019                    continue;
1020                }
1021                TokenKind::Punctuator(Punctuator::RightParen) => {
1022                    depth = depth.saturating_sub(1);
1023                    continue;
1024                }
1025                _ => {}
1026            }
1027            if depth != 0 {
1028                continue;
1029            }
1030            match token.keyword() {
1031                Some(Keyword::SELECT) | Some(Keyword::VALUES) => return StatementClass::ReadOnly,
1032                Some(Keyword::INSERT) | Some(Keyword::UPDATE) | Some(Keyword::DELETE) => {
1033                    return StatementClass::Write
1034                }
1035                _ => {}
1036            }
1037        }
1038    }
1039    match first.keyword() {
1040        Some(Keyword::SELECT) | Some(Keyword::VALUES) => StatementClass::ReadOnly,
1041        Some(Keyword::INSERT)
1042        | Some(Keyword::REPLACE)
1043        | Some(Keyword::UPDATE)
1044        | Some(Keyword::DELETE) => StatementClass::Write,
1045        Some(Keyword::CREATE)
1046        | Some(Keyword::DROP)
1047        | Some(Keyword::ALTER)
1048        | Some(Keyword::REINDEX)
1049        | Some(Keyword::ANALYZE)
1050        | Some(Keyword::VACUUM) => StatementClass::SchemaChange,
1051        Some(Keyword::BEGIN)
1052        | Some(Keyword::COMMIT)
1053        | Some(Keyword::END)
1054        | Some(Keyword::ROLLBACK)
1055        | Some(Keyword::SAVEPOINT)
1056        | Some(Keyword::RELEASE) => StatementClass::TransactionControl,
1057        Some(Keyword::PRAGMA) => StatementClass::Pragma,
1058        Some(Keyword::ATTACH) | Some(Keyword::DETACH) => StatementClass::SchemaChange,
1059        _ => StatementClass::Unknown,
1060    }
1061}