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}