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