-
Notifications
You must be signed in to change notification settings - Fork 675
[Oracle] Lower StringConcat precedence #2115
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
base: main
Are you sure you want to change the base?
Conversation
1307704 to
d57daaf
Compare
d57daaf to
1914d72
Compare
| fn oracle_dialect() -> TestedDialects { | ||
| TestedDialects::new(vec![Box::new(OracleDialect)]) | ||
| } | ||
|
|
||
| /// Wraps [Expr::BinaryExpr]s in `item` with a [Expr::Nested] recursively. | ||
| fn nest_binary_ops(item: &mut SelectItem) { | ||
| // ~ idealy, we could use `VisitorMut` at this point | ||
| fn nest(expr: &mut Expr) { | ||
| // ~ ideally we could use VisitorMut here | ||
| if let Expr::BinaryOp { left, op: _, right } = expr { | ||
| nest(&mut *left); | ||
| nest(&mut *right); | ||
| let inner = std::mem::replace(expr, Expr::Value(Value::Null.into())); | ||
| *expr = Expr::Nested(Box::new(inner)); | ||
| } | ||
| } | ||
| match item { | ||
| SelectItem::UnnamedExpr(expr) => nest(expr), | ||
| SelectItem::ExprWithAlias { expr, alias: _ } => nest(expr), | ||
| SelectItem::QualifiedWildcard(_, _) => {} | ||
| SelectItem::Wildcard(_) => {} | ||
| } | ||
| } |
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.
can we move these to the top of the file instead? folks tend to add new tests to the bottom of the file, so that these don't end up awkwardly in the middle over time.
| ); | ||
| } | ||
|
|
||
| fn oracle_dialect() -> TestedDialects { |
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.
| fn oracle_dialect() -> TestedDialects { | |
| fn oracle() -> TestedDialects { |
| #![warn(clippy::all)] | ||
| //! Test SQL syntax, specific to [sqlparser::dialect::OracleDialect]. | ||
| extern crate core; |
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.
what's this used for?
|
|
||
| #![warn(clippy::all)] | ||
| //! Test SQL syntax, specific to [sqlparser::dialect::OracleDialect]. |
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.
| #![warn(clippy::all)] | |
| //! Test SQL syntax, specific to [sqlparser::dialect::OracleDialect]. |
is the clippy attribute necessary here?
|
|
||
| /// If this `SetExpr` is a `SELECT`, returns a mutable [`Select`]. | ||
| pub fn as_select_mut(&mut self) -> Option<&mut Select> { | ||
| if let Self::Select(select) = self { | ||
| Some(&mut **select) | ||
| } else { | ||
| None | ||
| } | ||
| } |
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 this `SetExpr` is a `SELECT`, returns a mutable [`Select`]. | |
| pub fn as_select_mut(&mut self) -> Option<&mut Select> { | |
| if let Self::Select(select) = self { | |
| Some(&mut **select) | |
| } else { | |
| None | |
| } | |
| } |
I think we would want to avoid a public mut API that is only used for internal tests, if needed it would likely make more sense as a helper function in the test module
| // ~ oracle: `+`, `-`, and `||` have the same precedence and parse from left-to-right | ||
| let sql = "SELECT 3 + 5 || '.3' || 7 - 9 FROM dual"; | ||
| let mut query = oracle_dialect().verified_query(sql); | ||
| nest_binary_ops(&mut query.body.as_select_mut().expect("not a SELECT").projection[0]); |
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 think instead of introducing the nest_binary_ops tfn hat mutates the ast, can we instead explicitly assert what we expect the ast to look like?
| Precedence::Ampersand => 23, | ||
| Precedence::Caret => 22, | ||
| Precedence::Pipe => 21, | ||
| Precedence::Between | Precedence::Eq | Precedence::Like | Precedence::Is => 20, |
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.
This looks like the only changes compared to the default dialect precedence, can we add tests demonstrating what they imply?
Also since we're manually overriding all the precedence values, it would be good to have test coverage for each variant here for oracle as well
No description provided.