-
Notifications
You must be signed in to change notification settings - Fork 39
fix: Fix distribution and plan enumeration #498
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
base: main
Are you sure you want to change the base?
Conversation
d7e65a4 to
a83ae18
Compare
56364bc to
09bcab9
Compare
2b6dc1f to
aceabf7
Compare
mbasmanova
left a comment
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.
This is a lot of changes. I'm not sure how to process these. Is there a way to break up the PR into smaller pieces?
axiom/optimizer/Schema.h
Outdated
| /// is equal (==) to the other locus. A Locus is referenced by raw pointer and | ||
| /// may be allocated from outside the optimization arena. It is immutable and | ||
| /// lives past the optimizer arena. | ||
| class Locus { |
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.
Are you removing this class? It is not mentioned in the PR description.
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.
Updated
aceabf7 to
a9f30dd
Compare
|
VELOX_CHECK_EQ(cost.inputCardinality, 1) is incorrect. This is correct only for the leaf RelationOp (scan). I'd like to first extend TableWrite to add support for writing partitioned tables. |
Can this be a separate PR?
Would you explain this a bit more? Can this be a separate PR? |
I think it's correct because cost is partial plan cost, not relation operator cost. I think main confusion with current code that Cost is actually 2 types of cost:
Hope this helps |
8250415 to
bd26d1d
Compare
c59fb5a to
848d6dc
Compare
|
@MBkkt I'm not able to parse this change. Would it be possible to describe a problem being fixes and how it is fixed? If the original problem is too messy to explain, perhaps, describe the new design you propose and how it works in all different scenarios? |
c7d319b to
0c9072e
Compare
|
@mbasmanova tpch.q9 in this PR starts to fail because of this #527 |
| if (isWorse(old)) { | ||
| // Remove old plan, it is worse than the new one in all aspects. | ||
| queryCtx()->optimization()->trace( | ||
| OptimizerOptions::kExceededBest, state.dt->id(), old.cost, *old.op); | ||
| std::swap(plans[i], plans.back()); | ||
| plans.pop_back(); | ||
| --i; | ||
| found = kFoundWorse; | ||
| } else if (found == kNone && isBetter(old)) { | ||
| // Old plan is better than the new one in all aspects. | ||
| found = kFoundBetter; | ||
| } | ||
| } | ||
| if (found == kFoundBetter) { | ||
| // No existing plan was worse than the new one in all aspects, | ||
| // and at least one existing plan is better than the new one in all aspects. | ||
| // So don't add the new plan. | ||
| return nullptr; | ||
| } |
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.
@mbasmanova I think one of main changes is this part of code. Everything else is related continuation.
What is doing new code?
We want to add new plan
In first we remove all old plans that is worse than new.
And if there's no such plans, and exists at least one old plan that is better than new, we don't need to add new plan.
Also we should account that plans can have different distribution (order and partition).
If order is not compatible, we cannot say one is worse or better.
If partition is not compatible, we need to account cost of reshuffle plan.
Old code
Did something strange?
- It didn't remove worse plans, it replaced only one of them
- It used incorrect checks to detect isBetter plan, like
!old->isStateBetter(state, -shuffleCostPerRow)) - It used incorrect code to check distribution is same.
- It used incorrect cost computation (now it's formula written single time in single place)
079b039 to
f9f8fca
Compare
f9f8fca to
bbe428f
Compare
bbe428f to
2a41fae
Compare

If any questions "why", please ask, I spent some time in trying to understand what current code wants and what is actually written.
In short I did following:
DistributionType::numPartitions, because it was unused and confusingDistributionType::mode, because it was unused and confusingisSamePartitionbecause it was incorrect for broadcast at leastneedsShuffleinstead ofisSamePartition, it will work correct for broadcast and will allow more casesisSameOrderwithneedsSort, now if something has sort over "a, b" we don't need to resort for sort "a"Some Notes:
All current tests are passed except few with incorrect join order expected in the tests, such tests adjusted
In most places Cost::cost used as plan cost, plan input cardinality is always 1, so we can omit inputCardinality from computation for them. But in such case function will became invalid for relation. If needed we can have two functions
Currently input/result cardinality doesn't handle something like
select count(*) from (select 1 limit 0)Because cardinality stored as fanout and multiply doesn't handle this case in a good way.
I have idea how to fix this, but it will be done in the next PR (because requires some refactoring in how we process cost)
Follow ups: