I'm facing a similar problem but with Join inputs. Is there a way to control the type of nodes returned as inputs to a join ? I wrote a rule for a join but it failed to match it because I expect the join inputs to be *JdbcRel* nodes while the inputs were actually *HepRelVertex*. I'm using Drill.
- Gelbana On Fri, Jun 30, 2017 at 4:35 PM, Muhammad Gelbana <[email protected]> wrote: > Thanks a lot Julian. That was very helpful. > > *---------------------* > *Muhammad Gelbana* > > On Thu, Jun 29, 2017 at 8:04 PM, Julian Hyde <[email protected]> wrote: > >> Consider ProjectFilterTransposeRule, a simple rule that matches a Project >> on top of a Filter. But how to get that Project and Filter? >> >> Run RelOptRulesTest.testPushProjectPastFilter in the debugger, and put a >> breakpoint in ProjectFilterTransposeRule.onMatch [1]. Look at the >> Project “origProj” in the debugger. Its input is a HepRelVertex containing >> a Filter. But Filter “filter” is, sure enough, a Filter. >> >> So, to get the filter, don’t call origProj.getInput(), instead call >> call.rel(1). The RelOptRuleCall will have ensured that this is the correct >> type, and removed any wrappers. >> >> Julian >> >> >> [1] https://insight.io/github.com/apache/calcite/blob/master/cor >> e/src/main/java/org/apache/calcite/rel/rules/ProjectFilterTr >> ansposeRule.java?line=78 <https://insight.io/github.com >> /apache/calcite/blob/master/core/src/main/java/org/apache/ >> calcite/rel/rules/ProjectFilterTransposeRule.java?line=78> >> > On Jun 29, 2017, at 8:47 AM, Muhammad Gelbana <[email protected]> >> wrote: >> > >> > But how can I handle the unexpected variation of the input class type ? >> > For example, please consider the following *RelOptRule* constructor >> > >> > public IncortaLimitRule() { >> >> super(operand(*DrillLimitRel*.class, operand(*IncortaJdbcDrel*.clas >> s, >> >> operand(*JdbcRel*.class, any()))), "TestRule"); >> >> } >> > >> > >> > I'm trying to be precise so I specified the RelNode (*DrillLimitRel*), >> it's >> > input (*IncortaJdbcDrel*) and it's input's input (*JdbcRel*, this is an >> > interface but I understand that the planner should match relnodes if the >> > rule's operand is a parent of examined operand, so for instance, >> > *JdbcTableScan* should match). >> > >> > Is there a way to guarantee the relnode's input type ? Looking into >> other >> > rules, I don't remember seeing type checking for input relnodes. Is it a >> > good sign that I have to do multiple checks for the input relnode type ? >> > >> > *---------------------* >> > *Muhammad Gelbana* >> > >> > On Tue, Jun 27, 2017 at 1:36 AM, Julian Hyde <[email protected]> wrote: >> > >> >> 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 <[email protected]> >> >> 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* >> >> >> >> >> >> >
