alexander-beedie commented on code in PR #2227:
URL:
https://github.com/apache/datafusion-sqlparser-rs/pull/2227#discussion_r2846992281
##########
src/parser/mod.rs:
##########
@@ -1756,31 +1756,60 @@ impl<'a> Parser<'a> {
// ^^^^^^^^^^^^^^^^ ^^^^^^^^
// interval expression identifier
//
- // We first try to parse the word and following tokens as a
special expression, and if that fails,
- // we rollback and try to parse it as an identifier.
- let w = w.clone();
- match self.try_parse(|parser|
parser.parse_expr_prefix_by_reserved_word(&w, span)) {
- // This word indicated an expression prefix and parsing
was successful
- Ok(Some(expr)) => Ok(expr),
-
- // No expression prefix associated with this word
- Ok(None) =>
Ok(self.parse_expr_prefix_by_unreserved_word(&w, span)?),
-
- // If parsing of the word as a special expression failed,
we are facing two options:
- // 1. The statement is malformed, e.g. `SELECT INTERVAL '1
DAI` (`DAI` instead of `DAY`)
- // 2. The word is used as an identifier, e.g. `SELECT
MAX(interval) FROM tbl`
- // We first try to parse the word as an identifier and if
that fails
- // we rollback and return the parsing error we got from
trying to parse a
- // special expression (to maintain backwards compatibility
of parsing errors).
- Err(e) => {
- if !self.dialect.is_reserved_for_identifier(w.keyword)
{
- if let Ok(Some(expr)) = self.maybe_parse(|parser| {
-
parser.parse_expr_prefix_by_unreserved_word(&w, span)
- }) {
- return Ok(expr);
+ if w.keyword == Keyword::NoKeyword {
+ // Fast path: for non-keyword words not followed by
+ // special tokens, produce an identifier directly.
+ let peek = &self.peek_token_ref().token;
+ let is_special = matches!(
+ peek,
+ Token::LParen
+ | Token::Arrow
+ | Token::SingleQuotedString(_)
+ | Token::DoubleQuotedString(_)
+ | Token::HexStringLiteral(_)
+ );
+ // Typed lambda: `a INT -> a * 2`
+ let is_typed_lambda = matches!(peek, Token::Word(_))
+ && self.dialect.supports_lambda_functions()
+ && self.peek_nth_token_ref(1).token == Token::Arrow;
+ if !is_special && !is_typed_lambda {
+ Ok(Expr::Identifier(w.to_ident(span)))
+ } else {
+ // Non-keyword followed by special token (e.g.
function call)
+ let w = w.clone();
+ Ok(self.parse_expr_prefix_by_unreserved_word(w, span)?)
+ }
Review Comment:
Sure, no problem. I can drop this part of the patch for now and see if
there's a simpler way to get the benefits of the fast path 🤔
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]