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

GH-4279 FilterOptimizer should not modify the query tree above the node it is currently on #4280

Merged
merged 1 commit into from
Nov 13, 2022

Conversation

hmottestad
Copy link
Contributor

GitHub issue resolved: #4279

Briefly describe the changes proposed in this PR:


PR Author Checklist (see the contributor guidelines for more details):

  • my pull request is self-contained
  • I've added tests for the changes I made
  • I've applied code formatting (you can use mvn process-resources to format from the command line)
  • I've squashed my commits where necessary
  • every commit message starts with the issue number (GH-xxxx) followed by a meaningful description of the change

Comment on lines 111 to 122
public void meet(Filter filter) {
super.meet(filter);
if (filter.getParentNode() instanceof Filter && filter.getParentNode().getParentNode() != null) {
if (filter.getArg() instanceof Filter && filter.getParentNode() != null) {

Filter parentFilter = (Filter) filter.getParentNode();
QueryModelNode grandParent = parentFilter.getParentNode();
And merge = new And(filter.getCondition().clone(), parentFilter.getCondition().clone());
Filter childFilter = (Filter) filter.getArg();
QueryModelNode parent = filter.getParentNode();
And merge = new And(childFilter.getCondition().clone(), filter.getCondition().clone());

Filter newFilter = new Filter(filter.getArg().clone(), merge);
grandParent.replaceChildNode(parentFilter, newFilter);
meet(newFilter);
Filter newFilter = new Filter(childFilter.getArg().clone(), merge);
parent.replaceChildNode(filter, newFilter);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pulquero your solution works well. I wasn't able to create a test that reproduces the issue. I found that when I removed the line with meet(newFilter); then I got some failing tests. Your solution made those tests pass again.

I think that meet(newFilter); was masking the issue. We would first recurse down to the innermost filter, then optimise it by swapping out the parent node. When returning back up we would visit the old parent node and if that node also needed to be optimised we would actually end up optimising the child nodes again.

Choose a reason for hiding this comment

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

Test case i think would be join, filter, filter, filter, sp for left arg and sp for right arg. Or the other way round. At the bottom it'll swap join with filter, but as it unwinds a 2nd time, the local filter var will be the old one it had on the way down, not the new one that it has been replaced by.

@hmottestad hmottestad merged commit 336e00c into main Nov 13, 2022
@hmottestad hmottestad deleted the GH-4279-filter-optimizer branch November 13, 2022 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Weakness/bug in FilterOptimizer
3 participants