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

Reply via email to