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