You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[refine](function) enforce final on CRTP aggregate function derived classes to enable compiler devirtualization (#62433)
`IAggregateFunctionHelper<Derived>` implements hot aggregate paths such
as `add_batch()` and `add_batch_single_place()` by calling
`assert_cast<const Derived*>(this)->add(...)`. Because `add()` is
declared `virtual` in `IAggregateFunction`, the compiler cannot
devirtualize this call unless it can prove that `Derived` has no further
overrides — which requires `Derived` to be marked `final`.
This PR enforces this via a `static_assert` in the
`IAggregateFunctionHelper` constructor. Note that `final` here is a
**performance hint only** — correctness is not affected, since `add()`
remains virtual and subclasses always dispatch correctly through the
vtable regardless. Marking `Derived` as `final` allows the compiler to
devirtualize (and potentially inline) the `add()` call inside hot
aggregation paths.
Changes:
1. Add a `static_assert` in the `IAggregateFunctionHelper` constructor
asserting `std::is_final_v<Derived>`, so that missing `final` is caught
at compile time.
2. Introduce `AggregateFunctionNonFinalBase` as an opt-out marker for
classes that intentionally form inheritance hierarchies (e.g.
`AggregateStateUnion → AggregateStateMerge`, `AggregateFunctionForEach →
AggregateFunctionForEachV2`).
3. Mark all concrete aggregate function classes `final` across
`be/src/exprs/aggregate/`.
4. Refactor `AggregateFunctionTopNBase` to accept a `Derived` template
parameter so that `AggregateFunctionTopN` and
`AggregateFunctionTopNArray` can each be marked `final`.
5. Refactor `AggregateFunctionPercentileApprox` into
`AggregateFunctionPercentileApproxBase<Derived>` so the four concrete
specializations can each be marked `final`.
0 commit comments