This is an automated email from the ASF dual-hosted git repository.
LucaCappelletti94 pushed a commit to branch visit-node-hooks
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/visit-node-hooks by this push:
new 058564712 Add NodeRef::variant_name
058564712 is described below
commit 058564712b8f9c6046e5cbbeb776bd2160dcb92c
Author: LucaCappelletti94 <[email protected]>
AuthorDate: Thu Sep 24 10:10:44 2026 +0200
Add NodeRef::variant_name
---
derive/src/visit.rs | 12 ++++++++++++
src/ast/visitor.rs | 54 ++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/derive/src/visit.rs b/derive/src/visit.rs
index 30e03fff2..272ba2dfc 100644
--- a/derive/src/visit.rs
+++ b/derive/src/visit.rs
@@ -53,6 +53,17 @@ pub(crate) fn derive_visit(
let (pre_visit, post_visit) = attributes.visit(quote!(self));
let children = visit_children(&input.data, visit_type);
let (pre_visit_node, post_visit_node) = if modifier.is_none() {
+ let variant_name = match &input.data {
+ Data::Enum(data) => {
+ let arms = data.variants.iter().map(|v| {
+ let name = &v.ident;
+ let text = name.to_string();
+ quote!(Self::#name { .. } =>
::core::option::Option::Some(#text))
+ });
+ quote!(match self { #(#arms),* })
+ }
+ _ => quote!(::core::option::Option::None),
+ };
(
Some(quote! {
let node = {
@@ -64,6 +75,7 @@ pub(crate) fn derive_visit(
sqlparser::ast::NodeRef::__new(
self,
::core::any::type_name::<Self>(),
+ #variant_name,
(&&probe).spanned(),
(&&probe).display(),
)
diff --git a/src/ast/visitor.rs b/src/ast/visitor.rs
index cd2d3309c..55bf5ba0a 100644
--- a/src/ast/visitor.rs
+++ b/src/ast/visitor.rs
@@ -73,6 +73,7 @@ pub trait VisitMut {
pub struct NodeRef<'a> {
any: &'a dyn Any,
type_name: &'static str,
+ variant_name: Option<&'static str>,
spanned: Option<&'a dyn Spanned>,
display: Option<&'a dyn fmt::Display>,
}
@@ -82,12 +83,14 @@ impl<'a> NodeRef<'a> {
pub fn __new(
any: &'a dyn Any,
type_name: &'static str,
+ variant_name: Option<&'static str>,
spanned: Option<&'a dyn Spanned>,
display: Option<&'a dyn fmt::Display>,
) -> Self {
Self {
any,
type_name,
+ variant_name,
spanned,
display,
}
@@ -103,6 +106,11 @@ impl<'a> NodeRef<'a> {
self.type_name
}
+ /// The name of the node's variant, if the node is an enum.
+ pub fn variant_name(&self) -> Option<&'static str> {
+ self.variant_name
+ }
+
/// The node, if its type implements [`Spanned`].
pub fn spanned(&self) -> Option<&'a dyn Spanned> {
self.spanned
@@ -1427,20 +1435,32 @@ mod tests {
assert_eq!(visitor.relations, vec!["db1.v", "t"]);
}
+ #[derive(Debug, PartialEq)]
+ struct Node {
+ depth: usize,
+ name: &'static str,
+ variant: Option<&'static str>,
+ spanned: bool,
+ display: Option<String>,
+ }
+
#[derive(Default)]
struct NodeVisitor {
depth: usize,
- nodes: Vec<(usize, &'static str, bool, Option<String>)>,
+ nodes: Vec<Node>,
}
impl Visitor for NodeVisitor {
type Break = ();
fn pre_visit_node(&mut self, node: NodeRef<'_>) ->
ControlFlow<Self::Break> {
- let name = node.type_name().rsplit("::").next().unwrap();
- let display = node.display().map(|d| d.to_string());
- self.nodes
- .push((self.depth, name, node.spanned().is_some(), display));
+ self.nodes.push(Node {
+ depth: self.depth,
+ name: node.type_name().rsplit("::").next().unwrap(),
+ variant: node.variant_name(),
+ spanned: node.spanned().is_some(),
+ display: node.display().map(|d| d.to_string()),
+ });
self.depth += 1;
ControlFlow::Continue(())
}
@@ -1464,22 +1484,30 @@ mod tests {
visitor
.nodes
.iter()
- .position(|(_, n, _, d)| *n == name && d.as_deref() ==
Some(display))
+ .position(|n| n.name == name && n.display.as_deref() ==
Some(display))
.unwrap_or_else(|| panic!("{name} `{display}` not visited"))
};
- let item = find("SelectItem", "CAST(a AS INT) AS x");
- assert!(visitor.nodes[item].2);
+ let item = &visitor.nodes[find("SelectItem", "CAST(a AS INT) AS x")];
+ assert!(item.spanned);
+ assert_eq!(item.variant, Some("ExprWithAlias"));
- let data_type = find("DataType", "INT");
- assert!(!visitor.nodes[data_type].2);
+ let data_type = &visitor.nodes[find("DataType", "INT")];
+ assert!(!data_type.spanned);
+ assert_eq!(data_type.variant, Some("Int"));
let join = find("Join", "JOIN u ON t.id = u.id");
- assert!(visitor.nodes[join].2);
- let (join_depth, ..) = visitor.nodes[join];
+ assert!(visitor.nodes[join].spanned);
+ assert_eq!(visitor.nodes[join].variant, None);
assert_eq!(
visitor.nodes[join + 1],
- (join_depth + 1, "TableFactor", true, Some("u".to_string()))
+ Node {
+ depth: visitor.nodes[join].depth + 1,
+ name: "TableFactor",
+ variant: Some("Table"),
+ spanned: true,
+ display: Some("u".to_string()),
+ }
);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]