Line data Source code
1 : //! The parse context.
2 : //!
3 : //! The grammar actions build the AST through the parse context. Nodes are appended to a flat buffer
4 : //! in post-order: `object` and `array` emit the children of a node and return the node itself,
5 : //! which the enclosing rule emits later. Every method takes `&self` (the state sits in a
6 : //! [`StateCell`]) so that the translated actions can nest calls like
7 : //! `ctx.object(.., &[attr(.., ctx.array(..))])`, which emit nodes in argument evaluation order.
8 :
9 : // Release builds hand out a plain `&mut State` from `StateCell::borrow_mut`, so the `mut` that the
10 : // debug `RefMut` guard needs on `let mut state = ..` is unused there.
11 : #![cfg_attr(not(debug_assertions), allow(unused_mut))]
12 :
13 : use super::value::{ExprVariant, NodeList};
14 : use crate::names::NameRegistry;
15 : use crate::scanner::Symbol;
16 : use crate::span::TextSpan;
17 : use dashql_buffers::parser::{AttributeKey, ExpressionOperator, Node, NodeType, NumericType, SampleCountUnit, StatementType, SymbolSpan};
18 :
19 : /// The cell of the parse context state.
20 : ///
21 : /// Methods of the parse context borrow the state only within their own body and never call each
22 : /// other while holding a borrow. Debug builds check this with a `RefCell`, release builds skip the
23 : /// bookkeeping, which is a hot path of parsing (about a thousand borrows per statement).
24 : #[cfg(debug_assertions)]
25 : pub(crate) struct StateCell<T>(std::cell::RefCell<T>);
26 :
27 : #[cfg(debug_assertions)]
28 : impl<T> StateCell<T> {
29 7386 : fn new(value: T) -> Self {
30 7386 : Self(std::cell::RefCell::new(value))
31 7386 : }
32 695245 : pub(crate) fn borrow(&self) -> std::cell::Ref<'_, T> {
33 695245 : self.0.borrow()
34 695245 : }
35 2690023 : pub(crate) fn borrow_mut(&self) -> std::cell::RefMut<'_, T> {
36 2690023 : self.0.borrow_mut()
37 2690023 : }
38 7386 : fn into_inner(self) -> T {
39 7386 : self.0.into_inner()
40 7386 : }
41 : }
42 :
43 : /// The cell of the parse context state, unchecked in release builds
44 : #[cfg(not(debug_assertions))]
45 : pub(crate) struct StateCell<T>(std::cell::UnsafeCell<T>);
46 :
47 : #[cfg(not(debug_assertions))]
48 : impl<T> StateCell<T> {
49 : fn new(value: T) -> Self {
50 : Self(std::cell::UnsafeCell::new(value))
51 : }
52 : pub(crate) fn borrow(&self) -> &T {
53 : // SAFETY: borrows never overlap with a mutable borrow, checked by debug builds.
54 : unsafe { &*self.0.get() }
55 : }
56 : #[allow(clippy::mut_from_ref)]
57 : pub(crate) fn borrow_mut(&self) -> &mut T {
58 : // SAFETY: borrows never overlap, checked by debug builds.
59 : unsafe { &mut *self.0.get() }
60 : }
61 : fn into_inner(self) -> T {
62 : self.0.into_inner()
63 : }
64 : }
65 :
66 : /// The parent of nodes that have none (yet)
67 : pub const NO_PARENT: u32 = u32::MAX;
68 :
69 : /// A parsed statement
70 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
71 : pub struct Statement {
72 : /// The statement type, derived from the type of the root node
73 : pub statement_type: StatementType,
74 : /// The root node
75 : pub root: u32,
76 : /// The first node of the statement
77 : pub nodes_begin: u32,
78 : /// The number of nodes of the statement
79 : pub node_count: u32,
80 : }
81 :
82 : impl Default for Statement {
83 15738 : fn default() -> Self {
84 15738 : Self {
85 15738 : statement_type: StatementType::NONE,
86 15738 : root: u32::MAX,
87 15738 : nodes_begin: 0,
88 15738 : node_count: 0,
89 15738 : }
90 15738 : }
91 : }
92 :
93 : /// A parser error, located by symbol indexes
94 : #[derive(Clone, Debug, PartialEq)]
95 : pub struct ParseError {
96 : /// The symbol indexes of the error
97 : pub location: SymbolSpan,
98 : /// The error message
99 : pub message: String,
100 : /// A hint how to fix the error, empty if there is none
101 : pub hint: String,
102 : }
103 :
104 : /// An n-ary expression whose materialization is deferred to flatten conjunctions and disjunctions
105 : #[derive(Clone, Copy, Debug)]
106 : struct NaryExpression {
107 : /// The symbol indexes of the expression
108 : location: SymbolSpan,
109 : /// The operator, AND or OR
110 : op: ExpressionOperator,
111 : /// The operator node
112 : op_node: Node,
113 : /// The flattened arguments
114 : args: NodeList,
115 : }
116 :
117 : /// The mutable state of the parse context
118 : #[derive(Default)]
119 : pub(crate) struct State {
120 : /// The AST nodes in post-order
121 : pub(crate) nodes: Vec<Node>,
122 : /// The finished statements
123 : pub(crate) statements: Vec<Statement>,
124 : /// The parser errors
125 : pub(crate) errors: Vec<ParseError>,
126 : /// The names of the scanned script, extended by names the parser registers
127 : pub(crate) names: NameRegistry,
128 : /// The hint of the next error, produced while building a syntax error message
129 : pub(crate) pending_hint: String,
130 : /// Set by an action to drop the lookahead (`yyclearin`)
131 : pub(crate) clear_lookahead: bool,
132 : /// The statement being parsed, its nodes start at `nodes_begin`
133 : current_statement: Statement,
134 : /// The node lists indexed by list id
135 : lists: Vec<Vec<Node>>,
136 : /// Consumed lists whose allocation can be reused
137 : free_lists: Vec<u32>,
138 : /// The deferred n-ary expressions indexed by `ExprVariant::Nary` id
139 : nary_expressions: Vec<NaryExpression>,
140 : }
141 :
142 : impl State {
143 : /// A copy of the nodes of a list
144 81 : pub(crate) fn lists_snapshot(&self, list: NodeList) -> Vec<Node> {
145 81 : self.lists[list.0 as usize].clone()
146 81 : }
147 : }
148 :
149 : /// The parse context
150 : pub struct ParseContext<'a> {
151 : /// The script text
152 : text: &'a str,
153 : /// The scanned symbols, located by byte spans
154 : symbols: &'a [Symbol],
155 : /// The mutable parser state
156 : pub(crate) state: StateCell<State>,
157 : }
158 :
159 : /// Arguments that are node lists: list ids and node slices
160 : pub trait IntoNodeList {
161 : fn into_node_list(self, ctx: &ParseContext) -> NodeList;
162 : }
163 :
164 : impl IntoNodeList for NodeList {
165 216695 : fn into_node_list(self, _ctx: &ParseContext) -> NodeList {
166 216695 : self
167 216695 : }
168 : }
169 :
170 : impl<const N: usize> IntoNodeList for &[Node; N] {
171 174860 : fn into_node_list(self, ctx: &ParseContext) -> NodeList {
172 174860 : ctx.list(&self[..])
173 174860 : }
174 : }
175 :
176 : impl IntoNodeList for &[Node] {
177 0 : fn into_node_list(self, ctx: &ParseContext) -> NodeList {
178 0 : ctx.list(self)
179 0 : }
180 : }
181 :
182 : /// A node with replaced fields
183 966646 : fn with_parent(n: &Node, parent: u32) -> Node {
184 966646 : Node::new(n.symbol_span(), n.node_type(), n.attribute_key(), parent, n.children_begin_or_value(), n.children_count())
185 966646 : }
186 :
187 : /// The null node, skipped by `object` and `array`
188 143708 : pub fn null() -> Node {
189 143708 : Node::new(&SymbolSpan::default(), NodeType::NONE, AttributeKey::NONE, NO_PARENT, 0, 0)
190 143708 : }
191 :
192 : impl<'a> ParseContext<'a> {
193 7386 : pub fn new(text: &'a str, symbols: &'a [Symbol], names: NameRegistry) -> Self {
194 7386 : Self {
195 7386 : text,
196 7386 : symbols,
197 7386 : state: StateCell::new(State {
198 7386 : names,
199 7386 : nodes: Vec::with_capacity(symbols.len() * 3),
200 7386 : ..Default::default()
201 7386 : }),
202 7386 : }
203 7386 : }
204 :
205 : /// The scanned symbols
206 340741 : pub fn symbols(&self) -> &'a [Symbol] {
207 340741 : self.symbols
208 340741 : }
209 :
210 : /// Finish parsing and return the state
211 7386 : pub(crate) fn into_state(self) -> State {
212 7386 : self.state.into_inner()
213 7386 : }
214 :
215 : /// Resolve a span of symbol indexes to a span of bytes
216 596 : pub fn resolve_text_span(&self, span: SymbolSpan) -> TextSpan {
217 596 : resolve_text_span(self.text, self.symbols, span)
218 596 : }
219 :
220 : /// The text of a span of symbols
221 130 : fn text_at(&self, span: SymbolSpan) -> &'a str {
222 130 : let ts = self.resolve_text_span(span);
223 130 : &self.text[ts.offset as usize..ts.end() as usize]
224 130 : }
225 :
226 : // -----------------------------------------------------------------------------------------
227 : // Lists
228 : // -----------------------------------------------------------------------------------------
229 :
230 : /// Create a list
231 372604 : pub fn list(&self, nodes: &[Node]) -> NodeList {
232 372604 : let mut state = self.state.borrow_mut();
233 372604 : if let Some(id) = state.free_lists.pop() {
234 341637 : state.lists[id as usize].extend_from_slice(nodes);
235 341637 : return NodeList(id);
236 30967 : }
237 30967 : state.lists.push(nodes.to_vec());
238 30967 : NodeList(state.lists.len() as u32 - 1)
239 372604 : }
240 :
241 : /// Release a consumed list, keeping its allocation for reuse
242 370746 : fn recycle(&self, list: NodeList, mut nodes: Vec<Node>) {
243 370746 : nodes.clear();
244 370746 : let mut state = self.state.borrow_mut();
245 370746 : state.lists[list.0 as usize] = nodes;
246 370746 : state.free_lists.push(list.0);
247 370746 : }
248 :
249 : /// Append a node
250 101112 : pub fn push_back(&self, list: NodeList, node: Node) {
251 101112 : self.state.borrow_mut().lists[list.0 as usize].push(node);
252 101112 : }
253 :
254 : /// Prepend a node
255 9568 : pub fn push_front(&self, list: NodeList, node: Node) {
256 9568 : self.state.borrow_mut().lists[list.0 as usize].insert(0, node);
257 9568 : }
258 :
259 : /// Is a list empty?
260 1671 : pub fn list_is_empty(&self, list: NodeList) -> bool {
261 1671 : self.state.borrow().lists[list.0 as usize].is_empty()
262 1671 : }
263 :
264 : /// Move the nodes of a list
265 370746 : fn take_list(&self, list: NodeList) -> Vec<Node> {
266 370746 : std::mem::take(&mut self.state.borrow_mut().lists[list.0 as usize])
267 370746 : }
268 :
269 : /// Append the nodes of `other` to `list`
270 30622 : fn append(&self, list: NodeList, other: impl IntoNodeList) {
271 30622 : let other = other.into_node_list(self);
272 30622 : if other == list {
273 0 : return;
274 30622 : }
275 30622 : let nodes = self.take_list(other);
276 30622 : self.state.borrow_mut().lists[list.0 as usize].extend_from_slice(&nodes);
277 30622 : self.recycle(other, nodes);
278 30622 : }
279 :
280 : /// `Concat(l, r)`
281 19438 : pub fn concat2(&self, l: impl IntoNodeList, r: impl IntoNodeList) -> NodeList {
282 19438 : let l = l.into_node_list(self);
283 19438 : self.append(l, r);
284 19438 : l
285 19438 : }
286 :
287 : /// `Concat(v0, v1, v2)`
288 780 : pub fn concat3(&self, v0: impl IntoNodeList, v1: impl IntoNodeList, v2: impl IntoNodeList) -> NodeList {
289 780 : let v0 = v0.into_node_list(self);
290 780 : self.append(v0, v1);
291 780 : self.append(v0, v2);
292 780 : v0
293 780 : }
294 :
295 : /// `Concat(v0, v1, v2, v3)`
296 591 : pub fn concat4(
297 591 : &self,
298 591 : v0: impl IntoNodeList,
299 591 : v1: impl IntoNodeList,
300 591 : v2: impl IntoNodeList,
301 591 : v3: impl IntoNodeList,
302 591 : ) -> NodeList {
303 591 : let v0 = v0.into_node_list(self);
304 591 : self.append(v0, v1);
305 591 : self.append(v0, v2);
306 591 : self.append(v0, v3);
307 591 : v0
308 591 : }
309 :
310 : // -----------------------------------------------------------------------------------------
311 : // Nodes
312 : // -----------------------------------------------------------------------------------------
313 :
314 : /// Emit a node and set the parent of its children
315 487637 : pub fn add_node(&self, node: Node) -> u32 {
316 487637 : let mut state = self.state.borrow_mut();
317 487637 : let node_id = state.nodes.len() as u32;
318 487637 : state.nodes.push(with_parent(&node, node_id));
319 487637 : let node_type = node.node_type();
320 487637 : if (node_type == NodeType::ARRAY || node_type.0 > NodeType::OBJECT_KEYS_.0) && node.children_count() > 0 {
321 308056 : let begin = node.children_begin_or_value() as usize;
322 308056 : let end = begin + node.children_count() as usize;
323 479009 : for child in &mut state.nodes[begin..end] {
324 479009 : *child = with_parent(child, node_id);
325 479009 : }
326 179581 : }
327 487637 : node_id
328 487637 : }
329 :
330 : /// Emit the children of a list and return their range, skipping null nodes
331 340124 : fn emit_children(&self, list: NodeList) -> (u32, u32) {
332 340124 : let begin = self.state.borrow().nodes.len() as u32;
333 340124 : let nodes = self.take_list(list);
334 618027 : for node in &nodes {
335 618027 : if node.node_type() == NodeType::NONE {
336 138742 : continue;
337 479285 : }
338 479285 : self.add_node(*node);
339 : }
340 340124 : self.recycle(list, nodes);
341 340124 : let n = self.state.borrow().nodes.len() as u32 - begin;
342 340124 : (begin, n)
343 340124 : }
344 :
345 : /// The span from the first to the last of `n` nodes starting at `begin`
346 0 : fn shrunk_location(&self, begin: u32, n: u32) -> SymbolSpan {
347 0 : let state = self.state.borrow();
348 0 : let first = state.nodes[begin as usize].symbol_span().offset();
349 0 : let last = state.nodes[(begin + n - 1) as usize].symbol_span();
350 0 : SymbolSpan::new(first, last.offset().wrapping_add(last.length()).wrapping_sub(first))
351 0 : }
352 :
353 : /// An array of nodes
354 165829 : pub fn array(&self, loc: SymbolSpan, values: impl IntoNodeList) -> Node {
355 165829 : self.array_ex(loc, values, true, false)
356 165829 : }
357 :
358 : /// An array of nodes with explicit options
359 165970 : pub fn array_ex(&self, mut loc: SymbolSpan, values: impl IntoNodeList, null_if_empty: bool, shrink_location: bool) -> Node {
360 165970 : let list = values.into_node_list(self);
361 165970 : let (begin, n) = self.emit_children(list);
362 165970 : if n == 0 && null_if_empty {
363 31361 : return null();
364 134609 : }
365 134609 : if n > 0 && shrink_location {
366 0 : loc = self.shrunk_location(begin, n);
367 134609 : }
368 134609 : Node::new(&loc, NodeType::ARRAY, AttributeKey::NONE, NO_PARENT, begin, n)
369 165970 : }
370 :
371 : /// An array of expressions
372 22638 : pub(crate) fn expression_array(&self, loc: SymbolSpan, exprs: &[ExprVariant]) -> Node {
373 22638 : let nodes = self.list(&[]);
374 46273 : for &expr in exprs {
375 46273 : let node = self.expression(expr);
376 46273 : self.push_back(nodes, node);
377 46273 : }
378 22638 : self.array(loc, nodes)
379 22638 : }
380 :
381 : /// An object
382 173553 : pub fn object(&self, loc: SymbolSpan, node_type: NodeType, attrs: impl IntoNodeList) -> Node {
383 173553 : self.object_ex(loc, node_type, attrs, true, false)
384 173553 : }
385 :
386 : /// An object with explicit options
387 174154 : pub fn object_ex(
388 174154 : &self,
389 174154 : mut loc: SymbolSpan,
390 174154 : node_type: NodeType,
391 174154 : attrs: impl IntoNodeList,
392 174154 : null_if_empty: bool,
393 174154 : shrink_location: bool,
394 174154 : ) -> Node {
395 174154 : let list = attrs.into_node_list(self);
396 174154 : let (begin, n) = self.emit_children(list);
397 174154 : if n == 0 && null_if_empty {
398 208 : return null();
399 173946 : }
400 173946 : if n > 0 && shrink_location {
401 0 : loc = self.shrunk_location(begin, n);
402 173946 : }
403 173946 : Node::new(&loc, node_type, AttributeKey::NONE, NO_PARENT, begin, n)
404 174154 : }
405 :
406 : /// Materialize an expression
407 101614 : pub fn expression(&self, expr: impl Into<ExprVariant>) -> Node {
408 101614 : match expr.into() {
409 97544 : ExprVariant::Node(node) => node,
410 4070 : ExprVariant::Nary(id) => {
411 4070 : let nary = self.state.borrow().nary_expressions[id as usize];
412 4070 : let args = self.array(nary.location, nary.args);
413 4070 : self.object(
414 4070 : nary.location,
415 : NodeType::OBJECT_SQL_NARY_EXPRESSION,
416 4070 : &[
417 4070 : super::actions::attr(AttributeKey::SQL_EXPRESSION_OPERATOR, nary.op_node),
418 4070 : super::actions::attr(AttributeKey::SQL_EXPRESSION_ARGS, args),
419 4070 : ],
420 : )
421 : }
422 : }
423 101614 : }
424 :
425 : /// Flatten an AND / OR expression with nested expressions of the same operator
426 34053 : pub(crate) fn try_merge(&self, loc: SymbolSpan, op_node: Node, args: &[ExprVariant]) -> Option<ExprVariant> {
427 34053 : if op_node.node_type() != NodeType::ENUM_SQL_EXPRESSION_OPERATOR {
428 96 : return None;
429 33957 : }
430 33957 : let op = ExpressionOperator(op_node.children_begin_or_value() as u8);
431 33957 : if op != ExpressionOperator::AND && op != ExpressionOperator::OR {
432 22034 : return None;
433 11923 : }
434 11923 : let nary_args = self.list(&[]);
435 11923 : let id = {
436 11923 : let mut state = self.state.borrow_mut();
437 11923 : state.nary_expressions.push(NaryExpression {
438 11923 : location: loc,
439 11923 : op,
440 11923 : op_node,
441 11923 : args: nary_args,
442 11923 : });
443 11923 : state.nary_expressions.len() as u32 - 1
444 : };
445 23846 : for &arg in args {
446 23846 : match arg {
447 14682 : ExprVariant::Node(node) => self.push_back(nary_args, node),
448 9164 : ExprVariant::Nary(child_id) => {
449 9164 : let child = self.state.borrow().nary_expressions[child_id as usize];
450 9164 : if child.op != op {
451 1313 : let node = self.expression(arg);
452 1313 : self.push_back(nary_args, node);
453 7853 : } else {
454 7851 : self.append(nary_args, child.args);
455 7851 : }
456 : }
457 : }
458 : }
459 11923 : Some(ExprVariant::Nary(id))
460 34053 : }
461 :
462 : // -----------------------------------------------------------------------------------------
463 : // Names
464 : // -----------------------------------------------------------------------------------------
465 :
466 : /// A name from a keyword. The symbol span, a span of token indexes, is registered as the name
467 : /// location (see docs/design/core_quirks.md).
468 1399 : pub fn name_from_keyword(&self, loc: SymbolSpan, text: &str) -> Node {
469 1399 : let id = self.state.borrow_mut().names.register(text, TextSpan::new(loc.offset(), loc.length()));
470 1399 : Node::new(&loc, NodeType::NAME, AttributeKey::NONE, NO_PARENT, id, 0)
471 1399 : }
472 :
473 : /// A name from a string literal. Only double quotes are trimmed, so single quotes are kept.
474 49 : pub fn name_from_string_literal(&self, loc: SymbolSpan) -> Node {
475 49 : let text = self.text_at(loc).trim_matches('"');
476 49 : let id = self.state.borrow_mut().names.register(text, TextSpan::new(loc.offset(), loc.length()));
477 49 : Node::new(&loc, NodeType::NAME, AttributeKey::NONE, NO_PARENT, id, 0)
478 49 : }
479 :
480 : /// Mark a trailing dot
481 43 : pub fn trailing_dot(&self, loc: SymbolSpan) -> Node {
482 43 : self.add_error(loc, "name has a trailing dot");
483 43 : Node::new(&loc, NodeType::OBJECT_EXT_TRAILING_DOT, AttributeKey::NONE, NO_PARENT, 0, 0)
484 43 : }
485 :
486 : // -----------------------------------------------------------------------------------------
487 : // Checks
488 : // -----------------------------------------------------------------------------------------
489 :
490 : /// The unit of a sample count written without one: the sampling methods of the SQL standard
491 : /// (`bernoulli`, `system`) take a percentage, every other sample takes a number of rows
492 11 : pub fn bare_sample_unit(&self, method: &Node, loc: SymbolSpan) -> Node {
493 11 : let is_percentage = method.node_type() == NodeType::NAME && {
494 11 : let state = self.state.borrow();
495 11 : matches!(state.names.get(method.children_begin_or_value()).text.as_str(), "bernoulli" | "system")
496 : };
497 11 : let unit = if is_percentage { SampleCountUnit::PERCENT } else { SampleCountUnit::ROWS };
498 11 : Node::new(&loc, NodeType::ENUM_SQL_SAMPLE_UNIT_TYPE, AttributeKey::NONE, NO_PARENT, unit.0 as u32, 0)
499 11 : }
500 :
501 : /// Report a FROM keyword that is not followed by a table reference. The rule stays lenient to
502 : /// keep the tree of an unfinished statement, but only the end of the input may follow the keyword.
503 33 : pub fn require_table_ref_after_from(&self, from: SymbolSpan) {
504 33 : let next = (from.offset() + from.length()) as usize;
505 33 : if self.symbols.get(next).is_some_and(|symbol| symbol.kind != crate::symbol_kind::S_YYEOF) {
506 18 : self.error(from, "expected a table reference after FROM");
507 29 : }
508 33 : }
509 :
510 : /// Read the precision of a float type
511 10 : pub fn read_float_type(&self, bits_loc: SymbolSpan) -> NumericType {
512 10 : let text = self.text_at(bits_loc);
513 10 : let digits: &str = &text[..text.bytes().take_while(u8::is_ascii_digit).count()];
514 10 : let bits: i64 = digits.parse().unwrap_or(0);
515 10 : if bits < 1 {
516 2 : self.add_error(bits_loc, "precision for float type must be least 1 bit");
517 8 : } else if bits < 24 {
518 4 : return NumericType::FLOAT4;
519 4 : } else if bits < 53 {
520 2 : return NumericType::FLOAT8;
521 2 : } else {
522 2 : self.add_error(bits_loc, "precision for float type must be less than 54 bits");
523 2 : }
524 4 : NumericType::FLOAT4
525 10 : }
526 :
527 : /// Require punctuation tokens to be adjacent in the source text
528 233 : pub fn require_adjacent(&self, left: SymbolSpan, right: SymbolSpan, spelling: &str) {
529 233 : let l = self.resolve_text_span(left);
530 233 : let r = self.resolve_text_span(right);
531 233 : if l.end() != r.offset {
532 12 : self.add_error(super::actions::loc(&[left, right]), &format!("expected adjacent punctuation \"{spelling}\""));
533 221 : }
534 233 : }
535 :
536 : /// Require a generic operator token to use an exact spelling
537 71 : pub fn require_operator(&self, loc: SymbolSpan, spelling: &str) {
538 71 : if self.text_at(loc) != spelling {
539 2 : self.add_error(loc, &format!("expected operator \"{spelling}\""));
540 69 : }
541 71 : }
542 :
543 : // -----------------------------------------------------------------------------------------
544 : // Statements and errors
545 : // -----------------------------------------------------------------------------------------
546 :
547 : /// Add a statement
548 12956 : pub fn add_statement(&self, node: Node) {
549 12956 : if node.node_type() == NodeType::NONE {
550 4604 : return;
551 8352 : }
552 8352 : let root = self.add_node(node);
553 8352 : let mut state = self.state.borrow_mut();
554 8352 : let statement_type = match node.node_type() {
555 30 : NodeType::OBJECT_EXT_SET => StatementType::SET,
556 70 : NodeType::OBJECT_SQL_CREATE_AS => StatementType::CREATE_TABLE_AS,
557 1687 : NodeType::OBJECT_SQL_CREATE => StatementType::CREATE_TABLE,
558 76 : NodeType::OBJECT_SQL_VIEW => StatementType::CREATE_VIEW,
559 69 : NodeType::OBJECT_SQL_CREATE_FUNCTION => StatementType::CREATE_FUNCTION,
560 5836 : NodeType::OBJECT_SQL_SELECT => select_statement_type(&state.nodes, node),
561 71 : NodeType::OBJECT_SQL_DROP_TABLE => StatementType::DROP_TABLE,
562 28 : NodeType::OBJECT_SQL_DROP_VIEW => StatementType::DROP_VIEW,
563 22 : NodeType::OBJECT_SQL_ATTACH_DATABASE => StatementType::ATTACH_DATABASE,
564 194 : NodeType::OBJECT_SQL_INSERT => StatementType::INSERT,
565 99 : NodeType::OBJECT_SQL_DELETE => StatementType::DELETE,
566 170 : NodeType::OBJECT_EXT_EXPLAIN => StatementType::EXPLAIN,
567 0 : other => panic!("unexpected statement root {:?}", other.variant_name()),
568 : };
569 8352 : let nodes_len = state.nodes.len() as u32;
570 8352 : let mut statement = state.current_statement;
571 8352 : statement.root = root;
572 8352 : statement.statement_type = statement_type;
573 8352 : statement.node_count = nodes_len - statement.nodes_begin;
574 8352 : state.statements.push(statement);
575 8352 : state.current_statement = Statement {
576 8352 : nodes_begin: nodes_len,
577 8352 : ..Default::default()
578 8352 : };
579 12956 : }
580 :
581 : /// Drop the nodes of the current statement after an error
582 337 : pub fn reset_statement(&self) {
583 337 : let mut state = self.state.borrow_mut();
584 337 : state.current_statement.nodes_begin = state.nodes.len() as u32;
585 337 : }
586 :
587 : /// Add an error without a hint
588 61 : pub fn add_error(&self, loc: SymbolSpan, message: &str) {
589 61 : self.state.borrow_mut().errors.push(ParseError {
590 61 : location: loc,
591 61 : message: message.to_string(),
592 61 : hint: String::new(),
593 61 : });
594 61 : }
595 :
596 : /// Report an error from the parser or an action, attaching the pending hint
597 311 : pub fn error(&self, loc: SymbolSpan, message: &str) {
598 311 : let mut state = self.state.borrow_mut();
599 311 : let hint = std::mem::take(&mut state.pending_hint);
600 311 : state.errors.push(ParseError {
601 311 : location: loc,
602 311 : message: message.to_string(),
603 311 : hint,
604 311 : });
605 311 : }
606 :
607 : /// Drop the lookahead after the action (`yyclearin`)
608 602 : pub fn clear_lookahead(&self) {
609 602 : self.state.borrow_mut().clear_lookahead = true;
610 602 : }
611 : }
612 :
613 : /// SELECT or SELECT INTO, following the inputs of set operations
614 5836 : fn select_statement_type(nodes: &[Node], root: Node) -> StatementType {
615 5836 : let mut current = root;
616 5881 : while current.node_type() == NodeType::OBJECT_SQL_SELECT {
617 5881 : let mut next = None;
618 5881 : let begin = current.children_begin_or_value() as usize;
619 14362 : for child in &nodes[begin..begin + current.children_count() as usize] {
620 14362 : if child.attribute_key() == AttributeKey::SQL_SELECT_INTO && child.node_type() != NodeType::NONE {
621 59 : return StatementType::SELECT_INTO;
622 14303 : }
623 14303 : if child.attribute_key() == AttributeKey::SQL_COMBINE_INPUT
624 45 : && child.node_type() == NodeType::ARRAY
625 45 : && child.children_count() > 0
626 45 : {
627 45 : next = Some(nodes[child.children_begin_or_value() as usize]);
628 14258 : }
629 : }
630 5822 : match next {
631 45 : Some(n) => current = n,
632 5777 : None => break,
633 : }
634 : }
635 5777 : StatementType::SELECT
636 5836 : }
637 :
638 : /// Resolve a span of symbol indexes to a span of bytes
639 231462 : pub fn resolve_text_span(text: &str, symbols: &[Symbol], span: SymbolSpan) -> TextSpan {
640 231462 : if span.length() == 0 {
641 243 : return match symbols.get(span.offset() as usize) {
642 243 : Some(symbol) => TextSpan::new(symbol.location.offset, 0),
643 0 : None => TextSpan::new(text.len() as u32, 0),
644 : };
645 231219 : }
646 231219 : let first = symbols[span.offset() as usize].location;
647 231219 : let last = symbols[(span.offset() + span.length() - 1) as usize].location;
648 231219 : TextSpan::new(first.offset, last.end() - first.offset)
649 231462 : }
|