-
Notifications
You must be signed in to change notification settings - Fork 572
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
Add derive based AST visitor #765
Conversation
Thanks @tustvold -- I will check this one out carefully, but probably not until tomorrow |
Thank you -- I plan to review this carefully later today |
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.
Thank you @tustvold -- I just had a chance to go through this code in more detail 👍
I think it works well for the usecase of visiting parts
I also spent some time comparing it to the approach in #601 and I had a queston:
How hard do you think it would be to add the following features (in the future):
- A
Rewriter
/ mutator for performing SQL rewrites in addition to visiting, - A
previsit()
andpostvisit()
to specify the order in which children were visted (DFS or BFS)? - Additional "visit" methods (e.g. if I wanted to visit all
Ident
s)? Could this be done in the proc macro itself? It seems like Drive proposed in Add an AST visitor #601 can do so.
I think 3. would be particularly compelling for other users of this crate in the near term.
cc @lovasoa -- I wonder if you have thoughts on this API
cc @AugustoFKL for your guidance
name = "sqlparser_derive" | ||
description = "proc macro for sqlparser" | ||
version = "0.1.0" | ||
authors = ["Andy Grove <andygrove73@gmail.com>"] |
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.
🤔 maybe this should be something different. I will think about a more appropriate author -- maybe sqlparser-rs contributors
🤔
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.
TBH I'm not sure as well. Theoretically I'd say that the owner/creator should be the author, but since this is an expansion, not sure whether put both of you or just the @tustvold
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 it is ok as is
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 changed it to "sqlparser authors" in #775
@@ -32,6 +33,7 @@ serde = { version = "1.0", features = ["derive"], optional = true } | |||
# of dev-dependencies because of | |||
# https://github.com/rust-lang/cargo/issues/1596 | |||
serde_json = { version = "1.0", optional = true } | |||
sqlparser_derive = { version = "0.1", path = "derive", optional = true } |
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.
Note to myself: if we merge this PR I think we should document this feature flag -- it seems documentation is missing for the existing feature flags
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.
|
||
## Visit | ||
|
||
This crate contains a procedural macro that can automatically derive implementations of the `Visit` trait |
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.
Note to self -- this should have a doc link back to the sqlparser crate
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.
in #779
@@ -337,6 +341,7 @@ fn format_datetime_precision_and_tz( | |||
/// guarantee compatibility with the input query we must maintain its exact information. | |||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] | |||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | |||
#[cfg_attr(feature = "visitor", derive(Visit))] |
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 am a big fan of this method as a way to minimize maintenance burden on new contributions
I picked a random struct and removed the #[cfg_attr(feature = "visitor", derive(Visit))]
to see what would happen if it was forgotten
I think the error is fairly clear 👍
Compiling sqlparser v0.28.0 (/Users/alamb/Software/sqlparser-rs)
error[E0277]: the trait bound `ast::Password: visitor::Visit` is not satisfied
--> src/ast/mod.rs:1262:9
|
1262 | password: Option<Password>,
| ^^^^^^^^ the trait `visitor::Visit` is not implemented for `ast::Password`
|
= help: the following other types implement trait `visitor::Visit`:
Box<T>
CommentObject
CreateTableBuilder
Keyword
Option<T>
String
Vec<T>
ast::Action
and 120 others
note: required for `Option<ast::Password>` to implement `visitor::Visit`
--> src/ast/visitor.rs:21:16
|
21 | impl<T: Visit> Visit for Option<T> {
| ^^^^^ ^^^^^^^^^
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.
It's also making it easier to keep up with the merge conflicts 😆
src/ast/visitor.rs
Outdated
pub trait Visitor { | ||
type Break; | ||
|
||
/// Invoked for any tables, virtual or otherwise that appear in the AST |
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 please rename this to visit_relation
(which is a more general term for table / view / CTE, etc)?
@@ -2,6 +2,7 @@ | |||
# will have compiled files and executables | |||
/target/ | |||
/sqlparser_bench/target/ | |||
/derive/target/ |
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.
Also note to self
I tested using
cargo test --all --features=visitor
We need to add this feature to the CI tests
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.
Oh, that explains the poor coverage I guess
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 verified that the CI does run with --all-features
: https://github.com/sqlparser-rs/sqlparser-rs/actions/runs/3794845435/jobs/6453351547
Pull Request Test Coverage Report for Build 3794824925
💛 - Coveralls |
Very easy, it would simply be a case of adding the method to the
Currently the code implements previsit, it would be relatively straightforward to add an additional annotation to support post visit.
You could definitely apply the same broad approach to this problem, but without having a good idea as to what the API might look like, or what the precise use-case would be, I'm not sure how easy this would be in practice. I suspect rewriting SQL AST directly would be relatively non-trivial to do correctly, not to mention verbose, with a far better approach to first lower to some sort of logical/intermediate representation. |
I would love this to be merged! This re-implements the entire derive-visitor crate inside sqlparser-rs, as opposed to my approach in #601 that just added it as a dependency. But I would still be very happy if this were merged and we finally had a way to visit sql statements ! |
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.
@tustvold any reasons why the coverage is so small?
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 we should do it.
I'll plan to resolve outstanding conflicts and then add additional documentation / tests as a follow on PR.
Thank you @tustvold @AugustoFKL and @lovasoa
name = "sqlparser_derive" | ||
description = "proc macro for sqlparser" | ||
version = "0.1.0" | ||
authors = ["Andy Grove <andygrove73@gmail.com>"] |
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 it is ok as is
Thanks again all! |
Improved Docs: #778 |
Reimplements #758 but using a proc-macro.
One issue is that currently this will not dispatch to
visit_table_name
for statements where theObjectType
is parameterised, this isDrop
,ShowCreate
,Comment
. We could theoretically add askip_if
option down the line, but I wanted to keep things simple for now.