Part of #33.
What
A ReplacementStrategy (see the sub-issue introducing that trait) that rewrites Aggregate{ measures: [Avg{col}], .. } into the equivalent Aggregate{ measures: [Sum{col}, Count], .. } wrapped in a Project recomputing sum/count under the original output name — per Peilin's #33 comment: "Semantic-equivalent query re-writing (e.g. rewriting avg to sum/count) to increase the applicability of the below optimizations."
Why this doesn't need its own bespoke "is it worth it" heuristic
Earlier drafts of this idea needed a manual before/after CSE diff to decide whether rewriting helps. With the Cascades/Volcano search from the other sub-issue in place, that's unnecessary: both the original (Avg) and rewritten (Sum+Count) forms are simply two ReplacementSubDAG candidates at the same site. The search explores both; whichever one lets SharedSubtreeStrategy fire more elsewhere in the workload naturally produces a lower-cost candidate plan, and the cost model's final sort picks it — no separate speculative-diff mechanism needed.
Scope
Avg → Sum/Count only for the first landing (the concrete case in Peilin's comment).
- Other semantically-equivalent rewrites (e.g.
count(distinct x) forms already collapsing via canonicalization — verify no overlap before adding new ones) are follow-ups, not this issue.
Part of #33.
What
A
ReplacementStrategy(see the sub-issue introducing that trait) that rewritesAggregate{ measures: [Avg{col}], .. }into the equivalentAggregate{ measures: [Sum{col}, Count], .. }wrapped in aProjectrecomputingsum/countunder the original output name — per Peilin's #33 comment: "Semantic-equivalent query re-writing (e.g. rewriting avg to sum/count) to increase the applicability of the below optimizations."Why this doesn't need its own bespoke "is it worth it" heuristic
Earlier drafts of this idea needed a manual before/after CSE diff to decide whether rewriting helps. With the Cascades/Volcano search from the other sub-issue in place, that's unnecessary: both the original (
Avg) and rewritten (Sum+Count) forms are simply twoReplacementSubDAGcandidates at the same site. The search explores both; whichever one letsSharedSubtreeStrategyfire more elsewhere in the workload naturally produces a lower-cost candidate plan, and the cost model's final sort picks it — no separate speculative-diff mechanism needed.Scope
Avg → Sum/Countonly for the first landing (the concrete case in Peilin's comment).count(distinct x)forms already collapsing via canonicalization — verify no overlap before adding new ones) are follow-ups, not this issue.