You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Botong Huang (JIRA)" <ji...@apache.org> on 2019/07/22 02:21:00 UTC
[jira] [Updated] (CALCITE-3118) VolcanoRuleCall should look at
RelSubset rather than RelSet when checking child ordinal of a parent
operand
[ https://issues.apache.org/jira/browse/CALCITE-3118?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Botong Huang updated CALCITE-3118:
----------------------------------
Summary: VolcanoRuleCall should look at RelSubset rather than RelSet when checking child ordinal of a parent operand (was: Properly check child ordinal when matching parent operand in VolcanoRuleCall)
> VolcanoRuleCall should look at RelSubset rather than RelSet when checking child ordinal of a parent operand
> -----------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-3118
> URL: https://issues.apache.org/jira/browse/CALCITE-3118
> Project: Calcite
> Issue Type: Bug
> Reporter: Botong Huang
> Priority: Major
> Labels: pull-request-available
> Time Spent: 2h
> Remaining Estimate: 0h
>
> In VolcanoRuleCall.matchRecurse(), when ascending (child operand is matched, looking for parent operand match), we want to check that the matched parent indeed has the previously matched RelNode as a child *with the* *expected child ordinal*.
> However, there is a bug in this child ordinal check:
> {noformat}
> 333 if (ascending && operand.childPolicy != RelOptRuleOperandChildPolicy.UNORDERED) {
> 334 // We know that the previous operand was *a* child of its parent,
> 335 // but now check that it is the *correct* child.
> 336 final RelSubset input =
> 337 (RelSubset) rel.getInput(previousOperand.ordinalInParent);
> 338 List<RelNode> inputRels = input.set.getRelsFromAllSubsets();
> 339 if (!inputRels.contains(previous)) {
> 340 continue;
> 341 }
> 342 }
> {noformat}
> We intend to make sure that "previous" is in Subset "input". However line 338 looked at RelNodes from the entire RelSet, rather than RelNodes only in Subset "input". As a result, in some cases, incorrect parent is not skipped as expected and is matched incorrectly.
> The unit test case included is a case that triggers this bug, where a second child RelNode incorrectly get matched as the first child of the parent RelNode.
> --------------------------
> Here's a detailed explanation of the test case that triggers the bug
> We constructed a RelNode structure:
> {noformat}
> PhysBiRel
> / \
> Subset1 Subset2
> | |
> leftPhy rightPhy
> {noformat}
> Where PhysBiRel has two inputs: leftPhy and rightPhy, both are logically equivalent, but with different traits (Convention in this test case), and thus are in different subsets.
> (Two Rels in two subsets in the same RelSet is a necessary condition to trigger this bug. )
> A rule AssertOperandsDifferentRule is constructed as follows:
> {noformat}
> operand(PhysBiRel.class,
> operand(PhysLeafRel.class, any()),
> operand(PhysLeafRel.class, any()))
> {noformat}
> Obviously the correct match would be:
> {noformat}
> PhysBiRel
> / \
> leftPhy rightPhy
> {noformat}
> However, with the bug, another match is also returned:
> {noformat}
> PhysBiRel
> / \
> rightPhy rightPhy
> {noformat}
> *This is wrong because rightPhy is not PhysBiRel's first input at all, and should not match as parent operand's first child.*
> ----------------------------
> Here's how the incorrect match occurs.
> 1. When rightPhy of class PhysLeafRel is registered, we attempt to match it to both the left and right child operands of AssertOperandsDifferentRule above. This is expected.
> 2. When matched to the right child operand, it eventually leads to the correct match result above.
> 3. When matched to the left child operand, it should have skipped/failed matching the parent operand to PhysBiRel because rightPhy is *NOT* PhysBiRel's first input. But because of the bug, the match succeeded. After parent is matched, then it attempt to match the right child operand, and again matched the rightPhy. As a result, both child operand end up matching the same RelNode rightPhy.
--
This message was sent by Atlassian JIRA
(v7.6.14#76016)