Matthew, For the kinds of tasks that you mention, I tend to use the visitors. For example, to find whether can expression contains an IS NULL operator:
public static boolean containsIsNull(RexNode e) { try { e.accept(new RexVisitorImpl<Void>(true) { @Override public Void visitCall(RexCall call) { if (call.getKind() == SqlKind.IS_NULL) { throw Util.FoundOne.NULL; } return super.visitCall(call); } }); return false; } catch (Util.FoundOne x) { return true; } } There are many partially-baked utilities in RexUtil and SqlUtil, for example SqlUtil.containsIn calls SqlUtil.containsCall with a Predicate. Julian > On Jan 26, 2024, at 9:18 AM, Mihai Budiu <mbu...@gmail.com> wrote: > > Hello. > > I am not sure what you mean by "introspection". > I assume you have seen this blog post about the 3 calcite IRs that you > mention: https://www.feldera.com/blog/calcite-irs/ > > Visitors are the way to go for traversing these data structures. > > Mihai > ________________________________ > From: Matthew McMillian <matthewgmcmill...@gmail.com> > Sent: Thursday, January 25, 2024 7:28 PM > To: dev@calcite.apache.org <dev@calcite.apache.org> > Subject: [Question] Query Introspection on SqlNode, RexNode, and RelNode > > Hi Calcite Devs, > > Before I start, I just wanted to say that Calcite is a really awesome > framework! It's awesome to see a community come together to create such a > cool tool. > > For reference, I'm using Calcite 1.36. > > I'm newer to the Calcite ecosystem, but I have been experimenting with its > features for some time. I'm interested in using Calcite's different IRs > (SqlNode, RexNode, and RelNode in particular) to introspect a query. In > particular, I'm interested in analyzing a query's tree/plan and finding out > details about the query. Some examples to illustrate what I'm interested in > finding out (though not all the questions I might want to ask) are: > - At some arbitrary expression, what columns are referenced in that > expression? > - At some arbitrary expression, what functions are used in that expression? > - At some arbitrary expression, is this a subquery? > - At some arbitrary expression, what does the structure of the query look > like? Does it contain any subqueries or common table expressions? > > From what I've read in the JavaDocs, there are a few utilities that have > caught my eye, but I'm not 100% sure I'm looking in the right places. > - For SqlNode, I haven't noticed anything that can help me discover/collect > information from arbitrary nodes in a SqlNode tree. I've noticed that a > Visitor class is available, which is extremely useful. Does Calcite offer > any built-in introspection in this area, or is it expected that the > framework user extend the Visitor class to perform such introspection? > - For RexNode, I was unable to find anything that can allow me to > introspect RexNodes. I see that RexNodes also has a Visitor class, but I > have similar questions to the previous bullet point about built-in > introspection. In addition, I've also been unable to figure out how to > resolve RexInputRefs back to their source expressions so I could perform > analysis. > - For RelNode, I've found that the class RelMetadataQuery is very helpful > for analyzing a relational tree, but I've struggled to find out how to > introspect the details of LogicalProjects since a good chunk of the data > model's details (not structure) correspond to RexNodes. > > My question for the team is: I've read through the documentation and have > checked out the JavaDocs quite a bit, but I haven't been able to find > the idiomatic way to perform this type of introspection in Calcite. Does > the team have any pointers on what parts of the codebase are valuable for > this type of introspection? Is this type of introspection even possible in > vanilla Calcite, or is this something that I would need to extend myself? > Are some of the areas I've called out even the right places to look to > solve the kind of introspection questions I've mentioned? Any guidance / > pointers in this area to get me set in the right direction would be greatly > appreciated. > > Thank you for your time, > Matthew McMillian