Yes, to repeat: don’t call RelNode.getInput(int), or RelNode.getInputs(), or Join.getLeft() or Join.getRight(), or SingleRelNode.getInput(). If you do, you will get the wrapped input, a HepRelVertex or a RelSubset.
Instead call RelOptRuleCall.rel(int). Julian > On Aug 2, 2017, at 1:34 PM, Muhammad Gelbana <[email protected]> wrote: > > Of course! You are correct. I got used to single input nodes and I didn't > deal with the Join properly. > > I get the inputs of the join using *join.getInputs()*. > > > > Thanks, > Gelbana > > On Wed, Aug 2, 2017 at 8:10 PM, Julian Hyde <[email protected]> wrote: > >> Join has two inputs but you have only one “any()”. I am surprised that it >> is matching a Join at all (an operand with one input should not match a >> RelNode with two inputs). But given that it does… you have two operands, so >> call.rel(0) and call.rel(1) will be valid but call.rel(2) will not. >> >> So, how are you getting the right input to the join? Are you calling >> Join.getInput(1) or Join.getRight()? Yes, those will be HepRelVertex or >> RelSubset, as you are seeing. >> >> You should add another “, any()”, then call call.rel(2) when the rule >> matches. >> >> Julian >> >> >> >>> On Aug 2, 2017, at 3:15 AM, Muhammad Gelbana <[email protected]> >> wrote: >>> >>> Here it is >>> >>>> public GelbanaJoinRule(JdbcConvention out) { >>>> super(operand(LogicalJoin.class, Convention.NONE, any()), >>>> "GelbanaJoinRule"); >>>> this.outConvention = out; >>>> } >>> >>> >>> The nodes appearing as *HepRelVertex* are the *LogicalJoin*'s input >> nodes, >>> not the operands passed to the rule using the >>> *org.apache.calcite.plan.RelOptRule.matches(RelOptRuleCall)* method. >>> >>> >>> >>> - Gelbana >>> >>> On Tue, Aug 1, 2017 at 6:13 PM, Jess Balint <[email protected]> wrote: >>> >>>> Can you share your operand constraints? Where did you see HepRelVertex? >> As >>>> Julian described, the rel nodes are of the correct type when matched >> with >>>> operand constraints. >>>> >>>> Jess >>>> >>>> On Tue, Aug 1, 2017 at 7:25 AM, Muhammad Gelbana <[email protected]> >>>> wrote: >>>> >>>>> 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* >>>>>>>>> >>>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >> >>
