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* > >>>>>>> > >>>>>>> > >>>>> > >>>>> > >>>> > >>> > >> > >
