MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / parse_subexpr_seeded

Method parse_subexpr_seeded

src/sql-parser/src/parser.rs:570–608  ·  view source on GitHub ↗
(
        &mut self,
        precedence: Precedence,
        mut expr: Expr<Raw>,
    )

Source from the content-addressed store, hash-verified

568 }
569
570 fn parse_subexpr_seeded(
571 &mut self,
572 precedence: Precedence,
573 mut expr: Expr<Raw>,
574 ) -> Result<Expr<Raw>, ParserError> {
575 self.checked_recur_mut(|parser| {
576 // Each iteration wraps `expr` in one more node (a binary op, field
577 // access `a.b`, `IS`, etc.), so a long *flat* operator/field-access
578 // chain (`a.f.f.f…`, `a+a+a…`) builds AST depth iteratively — the
579 // per-call recursion guard above only counts as one level for the
580 // whole loop. Bound the chain length (at `EXPR_CHAIN_LIMIT`, not
581 // the much smaller `RECURSION_LIMIT` — flat chains are legitimate
582 // at widths deep nesting never reaches) so the resulting AST can't
583 // grow deep enough to overflow the stack when it is later
584 // displayed, dropped, cloned, or visited recursively. Regression
585 // for the parse_expr_roundtrip field-access-chain stack overflow
586 // (`a.ff.cX.*.G…`).
587 let mut chain = 0usize;
588 loop {
589 let next_precedence = parser.get_next_precedence();
590 if precedence >= next_precedence {
591 break;
592 }
593 chain += 1;
594 if chain > EXPR_CHAIN_LIMIT {
595 return Err(ParserError::new(
596 parser.peek_pos(),
597 format!(
598 "statement exceeds nested expression limit of {}",
599 EXPR_CHAIN_LIMIT
600 ),
601 ));
602 }
603
604 expr = parser.parse_infix(expr, next_precedence)?;
605 }
606 Ok(expr)
607 })
608 }
609
610 /// Parse an expression prefix
611 fn parse_prefix(&mut self) -> Result<Expr<Raw>, ParserError> {

Callers 2

parse_subexprMethod · 0.80

Calls 4

checked_recur_mutMethod · 0.80
get_next_precedenceMethod · 0.80
peek_posMethod · 0.80
parse_infixMethod · 0.80

Tested by

no test coverage detected