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
Iterative optimizer #6956
Iterative optimizer #6956
Conversation
7db2d56
to
d7b54c2
Compare
This makes it easier to extend the node hierarchy for tests in the upcoming iterative optimizer.
eea7ab9
to
1d57f9d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about these comments:
13e6b6a#r93578038
13e6b6a#r93575465
13e6b6a#r93576086
13e6b6a#r93576974
@@ -72,4 +74,11 @@ public Symbol getIdColumn() | |||
{ | |||
return visitor.visitAssignUniqueId(this, context); | |||
} | |||
|
|||
@Override | |||
public PlanNode replaceChildren(List<PlanNode> newChildren) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about renaming this to replaceSources
? You have getSources()
but replaceChildren
, it sounds like they were referencing to two different things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"sources" is a legacy term. It used to be accurate a long time ago, before we even had support for "index joins". Then, with that feature, and now with Apply, it can mean either source or subplan. So "child" is more correct now.
return node(idAllocator.getNextId(), source); | ||
} | ||
|
||
private GenericNode node(PlanNodeId id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could have only two node
methods:
node(PlanNodeId id, PlanNode ... sources);
node(PlanNode ... sources);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, duh! I renamed the old filter/project/join/values methods and forgot to deal with the duplication :)
int yGroup = getChildGroup(memo, memo.getRootGroup()); | ||
int zGroup = getChildGroup(memo, yGroup); | ||
|
||
PlanNode rewrittenW = memo.getNode(zGroup).getSources().get(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is just w
. There is no rewrite here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this node instance in particular, sure. Potentially, it's a rewritten node, because that's just what the memo does with every node in the plan tree in order to replace their children with group references.
In this case, I'm trying to simulate what a rule would see. It would not be correct to use w
directly.
|
||
Memo memo = new Memo(idAllocator, x); | ||
|
||
assertEquals(memo.getGroupCount(), 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not to use IterativeOptimizer
here with some simple lambda rule? Then you could also check the traversal of IterativeOptimizer
Something like:
optimizer(node -> if (node == y || node == z) return node(node.getSource())).optimize(x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could do that, but I wanted to test the Memo in isolation.
|
||
import static org.testng.Assert.assertEquals; | ||
|
||
public class TestMemo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a test for cycle? Rules can have bugs, so it would be nice to see how memo handles that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how a rule would be able to cause a cycle. Unless rules make up group ids out of thin air, I don't think it's possible to do so. Let me think about it.
@Config("experimental.iterative-optimizer-enabled") | ||
public FeaturesConfig setIterativeOptimizerEnabled(boolean value) | ||
{ | ||
this.newOptimizerEnabled = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename the field
It's enabled for all tests deriving from AbstractTestQueries. I didn't want to add another instance to avoid increasing build times.
I expect Lookup to evolve beyond just exposing stuff from Memo (e.g., to provide other things such as "traits" -- effective predicate, sortedness, cost, etc.) that doesn't belong in the Memo structure. We can always fold it into it if necessary.
Let me play with it. It might be over-engineering it.
I'll take a look. The exception may be a remnant from some intermediate code I was working on. Regardless, at some point we need to get rid of OutputNode. It serves no purpose other than a glorified ProjectNode. |
What about testing the other way round? Iterative optimizer is disabled by default which could hide some regressions in case that iterative optimizer "fixes" plan in case of bugs in legacy rules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one comment with testing cycle in Memo and IMO it is ready to go.
Turn on the new optimizer in prod, then? ;) In all seriousness, this is a challenge. Until we come up with a better story around how to deal with the matrix of features vs number of tests (i.e., #6910), we're going to have to live with compromises like this. |
Sounds good to me. ;)
Lets put #6910 to higher priority then, I will talk about it within TD. |
What about common subplan extraction? Bugs there could cause cycles. But ok, let's postpone this test until such rewrite (common subplan extraction) got possible.
pt., 23.12.2016, 09:07 użytkownik Martin Traverso <notifications@github.com>
napisał:
… ***@***.**** commented on this pull request.
------------------------------
In
presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/TestMemo.java
<#6956>:
> + * limitations under the License.
+ */
+package com.facebook.presto.sql.planner.iterative;
+
+import com.facebook.presto.sql.planner.PlanNodeIdAllocator;
+import com.facebook.presto.sql.planner.Symbol;
+import com.facebook.presto.sql.planner.plan.PlanNode;
+import com.facebook.presto.sql.planner.plan.PlanNodeId;
+import com.google.common.collect.ImmutableList;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestMemo
I'm not sure how a rule would be able to cause a cycle. Unless rules are
making up group ids out of thin air, I don't think it's possible to do so.
Let me think about it.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#6956>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AHN_-yIB81ksy7iiQ88tCfY3luLY9do4ks5rK4EzgaJpZM4LUh_M>
.
|
@Override | ||
public PlanNode replaceChildren(List<PlanNode> newChildren) | ||
{ | ||
return new MetadataDeleteNode(getId(), target, output, tableLayout); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert newChildren.isEmpty()
?
This optimizer decouples the traversal of the plan tree (IterativeOptimizer) from the transformation logic (Rule). The optimization loop applies rules recursively until a fixpoint is reached. It's implemented as PlanOptimizer so that it fits right into the existing framework.
This optimizer decouples the traversal of the plan tree (IterativeOptimizer)
from the transformation logic (Rule). The optimization loop applies rules
recursively until a fixpoint is reached.
It's implemented as PlanOptimizer so that it fits right into the existing
framework.
Extracted from #6700