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/core/src/main/java/org/apache/calcite/rel/rules/ProjectFilterTransposeRule.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 <m.gelb...@gmail.com> 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*.class,
>> 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 <jh...@apache.org> 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 <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*
>> 
>> 

Reply via email to