-
Notifications
You must be signed in to change notification settings - Fork 603
Add support for quantified comparison predicates (ALL/ANY/SOME) #1459
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
src/parser/mod.rs
Outdated
let right = if self.is_query_ahead() { | ||
// We have a subquery ahead (SELECT\WITH ...) need to rewind and | ||
// use the parenthesis for parsing the subquery as an expression. | ||
self.prev_token(); // SELECT |
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.
Would it make sense to call the self.prev_token()
as part of the is_query_ahead()
logic? Currently with the split it feels a bit disconnected that the method is abstracted but the caller here still has to know the details and manually rewind the token stream which seems like an arbitrary split of responsibility? So that if it works the same then the caller can only rely on the flag returned without knowing the details of how the check is done
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.
Yes, good idea, implemented in the new commit.
// use the parenthesis for parsing the subquery as an expression. | ||
self.prev_token(); // SELECT | ||
self.prev_token(); // LParen | ||
self.parse_subexpr(precedence)? |
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.
would it make sense to call self.try_parse_expr_sub_query()
here already? it seems like it could let us avoid most of the if block here
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.
I tried to make that work in the new commit, but since we need to rewind the LParen first it got a bit messy
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.
Ah right that makes sense!
src/parser/mod.rs
Outdated
@@ -12141,6 +12144,12 @@ impl<'a> Parser<'a> { | |||
pub fn into_tokens(self) -> Vec<TokenWithLocation> { | |||
self.tokens | |||
} | |||
|
|||
/// Checks if the next keyword indicates a query, i.e. SELECT or WITH | |||
pub fn is_query_ahead(&mut self) -> bool { |
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.
pub fn is_query_ahead(&mut self) -> bool { | |
fn peek_sub_query(&mut self) -> bool { |
also the function was made public, assuming that was unintentional?
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.
Fixed in new commit
src/parser/mod.rs
Outdated
@@ -12141,6 +12144,12 @@ impl<'a> Parser<'a> { | |||
pub fn into_tokens(self) -> Vec<TokenWithLocation> { | |||
self.tokens | |||
} | |||
|
|||
/// Checks if the next keyword indicates a query, i.e. SELECT or WITH |
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.
/// Checks if the next keyword indicates a query, i.e. SELECT or WITH | |
/// Returns true if the next keyword indicates a sub query, i.e. SELECT or WITH |
src/ast/mod.rs
Outdated
@@ -650,6 +650,8 @@ pub enum Expr { | |||
left: Box<Expr>, | |||
compare_op: BinaryOperator, | |||
right: Box<Expr>, | |||
// ANY and SOME are synonymous |
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.
Is there any one of the supported dialects supporting the SOME variant?
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.
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.
Ah cool! Can we include the link in the comment here as well? It could help later on in case someone comes across this and wonders the same
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.
Thanks @yoavcloud! Left a couple minor comment regarding doc links, other than that I think this looks good
src/ast/mod.rs
Outdated
@@ -650,6 +650,8 @@ pub enum Expr { | |||
left: Box<Expr>, | |||
compare_op: BinaryOperator, | |||
right: Box<Expr>, | |||
// ANY and SOME are synonymous |
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.
Ah cool! Can we include the link in the comment here as well? It could help later on in case someone comes across this and wonders the same
src/ast/mod.rs
Outdated
@@ -646,12 +646,16 @@ pub enum Expr { | |||
regexp: bool, | |||
}, | |||
/// `ANY` operation e.g. `foo > ANY(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]` | |||
/// https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#_8_9_quantified_comparison_predicate |
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.
I'm thinking we can link to snowflake instead? Since that's a supported dialect that has the subquery functionality. The current link doesnt seem to refer to any specific dialect so it could add confusion later on when trying to figure what features in the parser to maintain
// use the parenthesis for parsing the subquery as an expression. | ||
self.prev_token(); // SELECT | ||
self.prev_token(); // LParen | ||
self.parse_subexpr(precedence)? |
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.
Ah right that makes sense!
Pushed doc changes as recommended. |
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
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.
🚀 -- thanks @iffyio and @yoavcloud
Pull Request Test Coverage Report for Build 11261716771Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
@alamb can you please trigger the workflow again? Fixed an issue with the URLs in the docs |
Thanks again @yoavcloud |
Allows comparisons against subquery results: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#_8_9_quantified_comparison_predicate
For example: