The loosest precedence exposed on `expr`'s *right spine*, the precedence at which an operator printed immediately to its right would bind *into* it rather than wrap it. For a left operand / subject of a construct that prints to its right, this is what decides parenthesization (its mirror, [`left_edge`], decides right operands), because a prefix operator and the right operand of a binary/`BETWEEN`/
(expr: &Expr<T>)
| 736 | /// is unary `-`. Forms that close with a bracket on the right (`(…)`, `[…]`, |
| 737 | /// `::type`, `IS NULL`) are `ATOM`. |
| 738 | fn right_edge<T: AstInfo>(expr: &Expr<T>) -> u8 { |
| 739 | match expr { |
| 740 | // Right-transparent binary infixes: an operator tighter than this one |
| 741 | // binds into the right operand, which itself may expose a looser spine. |
| 742 | Expr::Or { right, .. } => prec::OR.min(right_edge(right)), |
| 743 | Expr::And { right, .. } => prec::AND.min(right_edge(right)), |
| 744 | Expr::Op { |
| 745 | op, expr2: Some(r), .. |
| 746 | } => binary_op_precedence(op).min(right_edge(r)), |
| 747 | // Prefix operators expose their operand's right spine. |
| 748 | Expr::Op { |
| 749 | op, |
| 750 | expr1, |
| 751 | expr2: None, |
| 752 | } => unary_prec(op).min(right_edge(expr1)), |
| 753 | Expr::Not { expr } => prec::NOT.min(right_edge(expr)), |
| 754 | // `IS DISTINCT FROM x` exposes `x`, while `IS NULL`/`TRUE`/… close. |
| 755 | Expr::IsExpr { |
| 756 | construct: IsExprConstruct::DistinctFrom(x), |
| 757 | .. |
| 758 | } => prec::IS.min(right_edge(x)), |
| 759 | // `… BETWEEN low AND high` exposes `high`. `… [I]LIKE pat [ESCAPE esc]` |
| 760 | // exposes the rightmost of `esc`/`pat`. |
| 761 | Expr::Between { high, .. } => prec::LIKE.min(right_edge(high)), |
| 762 | Expr::Like { |
| 763 | pattern, escape, .. |
| 764 | } => { |
| 765 | let rightmost = escape.as_deref().unwrap_or_else(|| pattern.as_ref()); |
| 766 | prec::LIKE.min(right_edge(rightmost)) |
| 767 | } |
| 768 | // Everything else closes on the right (a bracket, a keyword, a literal, |
| 769 | // or `IS NULL`-style), so nothing binds into it. |
| 770 | _ => prec::ATOM, |
| 771 | } |
| 772 | } |
| 773 | |
| 774 | /// The loosest precedence exposed on `expr`'s *left spine*, the mirror of |
| 775 | /// [`right_edge`]. For a *right* operand (an operator on its left), this is what |
no test coverage detected