[
https://issues.apache.org/jira/browse/CALCITE-926?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Maryann Xue updated CALCITE-926:
--------------------------------
Attachment: CALCITE-926.patch
Changing implementation of getParentRels() would also fix this problem, but I
suspect it might add some redundancy.
{code}
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
index b3e6a5e..1adebbd 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
@@ -236,7 +236,7 @@ protected String computeDigest() {
parentLoop:
for (RelNode parent : set.getParentRels()) {
for (RelSubset rel : inputSubsets(parent)) {
- if (rel.set == set && rel.getTraitSet().equals(traitSet)) {
+ if (rel.set == set && traitSet.satisfies(rel.getTraitSet())) {
list.add(parent);
continue parentLoop;
}
{code}
So I'm suggesting the fix in the patch, to return {{S1}} for {{convert(S1,
t2})} directly instead of creating a new subset {{S2}}.
> Rules cannot be matched because of missing "parent link"
> --------------------------------------------------------
>
> Key: CALCITE-926
> URL: https://issues.apache.org/jira/browse/CALCITE-926
> Project: Calcite
> Issue Type: Bug
> Reporter: Maryann Xue
> Assignee: Maryann Xue
> Attachments: CALCITE-926.patch
>
>
> There is no "parent link" in RelSubset, it is only for RelSet. However,
> RelSubset provides a "getParentRels()" link.
> {code}
> public Collection<RelNode> getParentRels() {
> final Set<RelNode> list = new LinkedHashSet<RelNode>();
> parentLoop:
> for (RelNode parent : set.getParentRels()) {
> for (RelSubset rel : inputSubsets(parent)) {
> if (rel.set == set && rel.getTraitSet().equals(traitSet)) {
> list.add(parent);
> continue parentLoop;
> }
> }
> }
> return list;
> }
> {code}
> Now that we have a RelNode {{P1}} and its input subset is {{S1}}, and we have
> a rule that matches {{P1}} and does the following:
> {code}
> onMatch(RelOptRuleCall call) {
> RelNode P1 = call.rel(0);
> RelNode S1 = P1.getInput(0);
> RelTraitSet t1 = S1.getTraitSet();
> RelTraitSet t2 = t1.replace(tx);
> RelNode S2 = convert(S1, t2);
> RelNode P2 = P1.copy(P1.getCluster, P1.getTraitSet(), S2);
> call.transformTo(P2);
> }
> {code}
> Note that {{t1}} is *NOT equal* to {{t2}}. So right now we have two subsets,
> {{S1}} and {{S2}}, in the same set; and their parents {{P1}} and {{P2}} in
> another set.
> {code}
> P1 P2
> | |
> S1(t1) S2(t2)
> {code}
> {{getParentRels(S1)}} would return {{P1}}, and {{getParentRels(S2)}} would
> return {{P2}}. This works fine except when {{t1}} satisfies {{t2}} (for
> instance, if {{tx}} is the empty collation trait) and as a result {{S2}}
> subsumes {{S1}}. Thus the expression {{S2 = convert(S1, t2)}} would
> eventually turn into {{S1}} after conversion, so {{P2}} is also a parent of
> {{S1}}, and {{getParentRels(S1)}} should return {{P1, P2}} instead.
> Suppose we have a second rule that should match {{P2 - R}} subsequently,
> {{R}} as some Rel in {{S1}}, it would NOT be fired since {{P2}} is not
> returned in the parent list of {{S1}}. It would not match {{R}} in {{S2}}
> either since it is in the form of {{P2 - AbstractConverter - R}}.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)