RelSubset provides a level of indirection that allows Calcite to optimize queries. If the input to a relational operator is an equivalence class, not a particular relational expression, then Calcite has the freedom to choose the member of the equivalence class that has the cheapest cost.
Calcite uses the Volcano algorithm, a form of dynamic programming, to do this. As you have discovered it means that you cannot simply tree-walk over a relational expression, looking for, say, a Project on top of a Filter. You need to write a RelOptRule that declares that it wants to see a Project on top of a Filter, and Volcano will fire that rule whenever that combination arises. Julian > On Jun 26, 2017, at 4:00 PM, Muhammad Gelbana <m.gelb...@gmail.com> wrote: > > While debugging through some of the rules I'm trying to get to work, I find > that the matched relnode's input is *HepRelVertex* or a *RelSubset*. > > Why wouldn't I be getting a descendant of the following types: > > - BiRel > - MultiJoin > - SetOp > - SingleRel > - TableScan > > There are other types too but I can assume how to handle the types I listed. > > *RelSubset* is really confusing because, as far as I understand, it's a > group of relnodes. So how can I decide which node to get from this group so > I can use it as an input to the new relnode I'm creating ?! Or should I > pass the *RelSubset* itself ? Why am I getting it in the first place and > not a single relnode ? > > *---------------------* > *Muhammad Gelbana*