Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CALCITE-3113] Equivalent MutableAggregates with different row types should match with each other. #1310

Closed
wants to merge 3 commits into from

Conversation

jinxing64
Copy link
Contributor

@jinxing64 jinxing64 commented Jul 9, 2019

In current code, below test case fails:

  @Test public void testAggregate1() {
    checkMaterialize(
        "select count(*) as c0 from \"emps\" group by \"empid\"",
        "select count(*) as c1 from \"emps\" group by \"empid\"");
  }

java.lang.AssertionError
    at org.apache.calcite.plan.SubstitutionVisitor.go(SubstitutionVisitor.java:504)
    at org.apache.calcite.plan.SubstitutionVisitor.go(SubstitutionVisitor.java:465)
    at org.apache.calcite.plan.MaterializedViewSubstitutionVisitor.go(MaterializedViewSubstitutionVisitor.java:56)
    at org.apache.calcite.plan.RelOptMaterializations.substitute(RelOptMaterializations.java:200)
    at org.apache.calcite.plan.RelOptMaterializations.useMaterializedViews(RelOptMaterializations.java:72)
    at org.apache.calcite.plan.volcano.VolcanoPlanner.registerMaterializations(VolcanoPlanner.java:347)

The reason is that MutableRel self-defined the identity mechanism. Obviously the materialization above should be used.

This PR proposes to do equivalence checking for row types but except for the field names.

I added two test cases in MaterializationTest, without this change, both of them fails.

@jinxing64 jinxing64 changed the title [CALCITE-3133] Equivalent MutableAggregates with different row types should match with each other. [CALCITE-3113] Equivalent MutableAggregates with different row types should match with each other. Jul 9, 2019
@jinxing64 jinxing64 force-pushed the CALCITE-3133 branch 2 times, most recently from 1a3b707 to 52b12b9 Compare July 9, 2019 15:26
@julianhyde
Copy link
Contributor

What do we do elsewhere (e.g. in RelOptRules)? Do we check whether row-types are the same modulo field names?

@danny0405
Copy link
Contributor

danny0405 commented Jul 10, 2019

What do we do elsewhere (e.g. in RelOptRules)? Do we check whether row-types are the same modulo field names?

My concern is the same, in RelOptPlanner, we think 2 rels are equivalent only their rowType and digest are all the same with each other, for row type equivalence, we mean the field names also need to be the same, should we sync this rule for MaterializedView ?

@jinxing64
Copy link
Contributor Author

@julianhyde @danny0405 THX a lot for review !
In this change, when targetDescendant==target, I add a compensation Project, thus the final replaced has exactly the same row-type as before.
When targetDescendant != target, I take two nodes with same digest but different row-types as equivalent, thus to achieve the matching, but this mismatch of row-types will not be visible in the final result.

if (targetDescendant == target) {
// A real substitution happens. We purge the attempted
// replacement list and add them into substitution list.
// Meanwhile we stop matching the descendants and jump
// to the next subtree in pre-order traversal.
assert result1.rowType.equals(result.call.query.rowType)
: Pair.of(result1, result.call.query);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert is not that necessary, because it is always true now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I will remove it.

result1 = MutableProject.of(
result.call.query.rowType, result.result, projects);
} else {
result1 = result.result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of new a MutableProject, can we just check the project list of the result row type ? If i'm not mistaken, only if the query and target have same row expressions but different alias can be matched, maybe we should only check the expression for alias.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't quite get it ~ Do you mean below ?

  1. No need to new a MutableProject, though the row type is different, we just let it go
  2. Add a check/assert for the row type, we allow name mismatch, but other parts of row type should match with each other

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't quite get it ~ Do you mean below ?

  1. No need to new a MutableProject, though the row type is different, we just let it go
  2. Add a check/assert for the row type, we allow name mismatch, but other parts of row type should match with each other

Yeah, that is just what i mean.

final RexBuilder rexBuilder = target.cluster.getRexBuilder();
List<RexNode> projects = new ArrayList<>(
rexBuilder.identityProjects(result.call.query.rowType));
result1 = MutableProject.of(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give the result1 a more readable name, how about equivalentResult ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that'd better.

@danny0405
Copy link
Contributor

I have give some advices for my understanding. But i'm not sure if it is better or worse when we allow to match of materializedView with different row type. Because our planning rules only consider strict row type match for equivalent rel nodes. Maybe @jcamachor can give a better review.

@jinxing64
Copy link
Contributor Author

THX, @danny0405 for your comments, I'll update the patch soon.

@jinxing64
Copy link
Contributor Author

@julianhyde
THX for your comments from JIRA. I updated this patch. Please take another look when you have time. In current code, I extracted out a Boolean rowTypesAreEquivalent(MutableRel rel0, MutableRel rel1, Litmus litmus) method for row type compatibility checking.

@rubenada
Copy link
Contributor

LGTM

@jinxing64
Copy link
Contributor Author

THX @rubenada for approving !

private boolean rowTypesAreEquivalent(
MutableRel rel0, MutableRel rel1, Litmus litmus) {
// Validation checking for row type, but except for the field names.
assert rel0.rowType.getFieldCount() == rel1.rowType.getFieldCount()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems redundant, because there is already a java doc comment for the method.

private boolean rowTypesAreEquivalent(
MutableRel rel0, MutableRel rel1, Litmus litmus) {
// Validation checking for row type, but except for the field names.
assert rel0.rowType.getFieldCount() == rel1.rowType.getFieldCount()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we still use this single assert and the other use the litmus ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THX Danny,
I updated, please check~

@danny0405 danny0405 added the LGTM-will-merge-soon Overall PR looks OK. Only minor things left. label Jul 17, 2019
@danny0405 danny0405 closed this in 0a87daf Jul 17, 2019
@jinxing64
Copy link
Contributor Author

@danny0405
THX for merging !

@jinxing64 jinxing64 deleted the CALCITE-3133 branch July 17, 2019 10:42
KhawlaMhb pushed a commit to KhawlaMhb/calcite that referenced this pull request Aug 5, 2019
…should match with each other(Jin Xing)

The MaterializedView now can match with eath other if the row fields
types equals but with different alias.

close apache#1310
wangxlong pushed a commit to wangxlong/calcite that referenced this pull request Feb 13, 2020
…should match with each other(Jin Xing)

The MaterializedView now can match with eath other if the row fields
types equals but with different alias.

close apache#1310
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LGTM-will-merge-soon Overall PR looks OK. Only minor things left.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants