Write `expr` as the receiver of a `.` operator (used by `FieldAccess` and `WildcardAccess`), parenthesizing when the receiver could re-bind the trailing dot on reparse. The `.` token has very high precedence and both the lexer and parser greedily extend adjacent tokens: `1.x` tokenizes the number `1.` and leaves `x` as an alias, and `'a'::T.x` consumes `T.x` as a qualified type name. The whitelist
(f: &mut AstFormatter<W>, expr: &Expr<T>)
| 574 | /// are a single `(…)`/`ARRAY(…)` primary, so a trailing dot attaches to the whole |
| 575 | /// thing.) |
| 576 | fn write_dot_receiver<W: fmt::Write, T: AstInfo>(f: &mut AstFormatter<W>, expr: &Expr<T>) { |
| 577 | let safe = matches!( |
| 578 | expr, |
| 579 | Expr::FieldAccess { .. } |
| 580 | | Expr::WildcardAccess(_) |
| 581 | | Expr::Parameter(_) |
| 582 | | Expr::Nested(_) |
| 583 | | Expr::Row { .. } |
| 584 | | Expr::Function(_) |
| 585 | | Expr::Case { .. } |
| 586 | | Expr::Exists(_) |
| 587 | | Expr::Subquery(_) |
| 588 | | Expr::Array(_) |
| 589 | | Expr::ArraySubquery(_) |
| 590 | | Expr::List(_) |
| 591 | | Expr::ListSubquery(_) |
| 592 | | Expr::Map(_) |
| 593 | | Expr::MapSubquery(_) |
| 594 | | Expr::Subscript { .. } |
| 595 | | Expr::HomogenizingFunction { .. } |
| 596 | | Expr::NullIf { .. } |
| 597 | | Expr::Value( |
| 598 | Value::String(_) |
| 599 | | Value::Boolean(_) |
| 600 | | Value::Null |
| 601 | | Value::HexString(_) |
| 602 | | Value::Interval(_) |
| 603 | ) |
| 604 | ); |
| 605 | if safe { |
| 606 | f.write_node(expr); |
| 607 | } else { |
| 608 | f.write_str("("); |
| 609 | f.write_node(expr); |
| 610 | f.write_str(")"); |
| 611 | } |
| 612 | } |
| 613 | |
| 614 | /// Write `left` as the LHS of `<left> <op> ANY/ALL (...)`. The printed `<op>` is an |
| 615 | /// ordinary binary infix. It can be any operator the parser accepts here, from |
no test coverage detected