-
Notifications
You must be signed in to change notification settings - Fork 616
Fallback to identifier parsing if expression parsing fails #1513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
787e396
to
d39af8d
Compare
77243eb
to
6685cce
Compare
src/parser/mod.rs
Outdated
} | ||
} | ||
|
||
fn parse_ident_expr(&mut self, w: &Word) -> Result<Expr, ParserError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm thinking we would need to rename the function, it seems to be doing more than identifiers (and based on the name its unclear what the word w
input argument is for)
6685cce
to
a2d92a4
Compare
src/parser/mod.rs
Outdated
Ok(Some(expr)) => Ok(expr), | ||
// This word indicated an expression prefix but parsing failed. Two options: | ||
// 1. Malformed statement | ||
// 2. The dialect may allow this word as identifier as well as indicating an expression |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments are indeed helpful to follow thanks! Thinking here we could clarify 2. even further with the SELECT MAX(interval) from tbl
example?
a2d92a4
to
1c5c90a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes look good to me overall! Left some minor comments then one regarding tests to demonstrate the new behavior
src/parser/mod.rs
Outdated
// special expression (to maintain backwards compatibility of parsing errors). | ||
Err(e) => { | ||
if !self.dialect.is_reserved_for_identifier(w.keyword) { | ||
if let Ok(expr) = self.maybe_parse_internal(|parser| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if let Ok(expr) = self.maybe_parse_internal(|parser| { | |
if let Some(expr) = self.maybe_parse(|parser| { |
it looks like we can use the normal maybe_parse here since it doesn't have the special requirement?
1c5c90a
to
e4ebe44
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! cc @alamb
This PR appears to have a small conflict |
…ifier if the expression parsing fails
e4ebe44
to
4486c20
Compare
@alamb resolved |
Thanks @yoavcloud |
This fixes the following issue: #1496
The parser encounters situations when the next keyword indicates an expression, but in fact it should be parsed as an identifier. Example from Snowflake:
SELECT MAX(interval) from tbl
. When the parser encounters theinterval
word it tries to parse anExpr::Interval
but it fails because in the context of this query,interval
is an identifier that Snowflake (unlike most other dialects) allows in unquoted form.The suggested approach is to try to parse the expression, but if that fails, fallback to parse an identifier under certain conditions. In addition, each dialect can now declare which keywords it reserves for use as an identifier in unquoted form.
Lastly, changed the parsing of the
DEFAULT
word to Expr::Default instead of an identifier.