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