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}