Skip to content

Commit 4ea8e36

Browse files
committed
Use single catch-all branch and check expr
1 parent e1ee4ee commit 4ea8e36

1 file changed

Lines changed: 45 additions & 33 deletions

File tree

src/parser/mod.rs

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,41 +1856,53 @@ impl<'a> Parser<'a> {
18561856
chain.push(AccessExpr::Dot(expr));
18571857
self.advance_token(); // The consumed string
18581858
}
1859-
// Handle words (including keywords like INTERVAL) as identifiers
1860-
// when they appear after a period. This ensures `T.interval` is
1861-
// parsed as a compound identifier, not as an interval expression.
1862-
// If followed by `(`, parse as a method call (but not for `(+)`
1863-
// which is the outer join operator in some dialects).
1864-
Token::Word(w) => {
1865-
let ident = w.clone().into_ident(next_token.span);
1866-
self.advance_token();
1867-
if self.peek_token() == Token::LParen && !self.peek_outer_join_operator() {
1868-
let expr = self.parse_function(ObjectName::from(vec![ident]))?;
1869-
chain.push(AccessExpr::Dot(expr));
1870-
} else {
1871-
chain.push(AccessExpr::Dot(Expr::Identifier(ident)));
1859+
// Fallback to parsing an arbitrary expression, but restrict to expression
1860+
// types that are valid after the dot operator. This ensures that e.g.
1861+
// `T.interval` is parsed as a compound identifier, not as an interval
1862+
// expression.
1863+
_ => {
1864+
let expr = self.maybe_parse(|parser| {
1865+
let expr = parser
1866+
.parse_subexpr(parser.dialect.prec_value(Precedence::Period))?;
1867+
match &expr {
1868+
Expr::CompoundFieldAccess { .. }
1869+
| Expr::CompoundIdentifier(_)
1870+
| Expr::Identifier(_)
1871+
| Expr::Value(_)
1872+
| Expr::Function(_) => Ok(expr),
1873+
_ => parser.expected("an identifier or value", parser.peek_token()),
1874+
}
1875+
})?;
1876+
1877+
match expr {
1878+
// If we get back a compound field access or identifier,
1879+
// we flatten the nested expression.
1880+
// For example if the current root is `foo`
1881+
// and we get back a compound identifier expression `bar.baz`
1882+
// The full expression should be `foo.bar.baz` (i.e.
1883+
// a root with an access chain with 2 entries) and not
1884+
// `foo.(bar.baz)` (i.e. a root with an access chain with
1885+
// 1 entry`).
1886+
Some(Expr::CompoundFieldAccess { root, access_chain }) => {
1887+
chain.push(AccessExpr::Dot(*root));
1888+
chain.extend(access_chain);
1889+
}
1890+
Some(Expr::CompoundIdentifier(parts)) => chain.extend(
1891+
parts.into_iter().map(Expr::Identifier).map(AccessExpr::Dot),
1892+
),
1893+
Some(expr) => {
1894+
chain.push(AccessExpr::Dot(expr));
1895+
}
1896+
// If the expression is not a valid suffix, fall back to
1897+
// parsing as an identifier. This handles cases like `T.interval`
1898+
// where `interval` is a keyword but should be treated as an identifier.
1899+
None => {
1900+
chain.push(AccessExpr::Dot(Expr::Identifier(
1901+
self.parse_identifier()?,
1902+
)));
1903+
}
18721904
}
18731905
}
1874-
// Fallback to parsing an arbitrary expression.
1875-
_ => match self.parse_subexpr(self.dialect.prec_value(Precedence::Period))? {
1876-
// If we get back a compound field access or identifier,
1877-
// we flatten the nested expression.
1878-
// For example if the current root is `foo`
1879-
// and we get back a compound identifier expression `bar.baz`
1880-
// The full expression should be `foo.bar.baz` (i.e.
1881-
// a root with an access chain with 2 entries) and not
1882-
// `foo.(bar.baz)` (i.e. a root with an access chain with
1883-
// 1 entry`).
1884-
Expr::CompoundFieldAccess { root, access_chain } => {
1885-
chain.push(AccessExpr::Dot(*root));
1886-
chain.extend(access_chain);
1887-
}
1888-
Expr::CompoundIdentifier(parts) => chain
1889-
.extend(parts.into_iter().map(Expr::Identifier).map(AccessExpr::Dot)),
1890-
expr => {
1891-
chain.push(AccessExpr::Dot(expr));
1892-
}
1893-
},
18941906
}
18951907
} else if !self.dialect.supports_partiql()
18961908
&& self.peek_token_ref().token == Token::LBracket

0 commit comments

Comments
 (0)