Fix runningAccumulate with nested states#105085
Conversation
|
Workflow [PR], commit [7fb4190] Summary: ✅
AI ReviewSummaryThis PR fixes Final VerdictStatus: ✅ Approve |
alexey-milovidov
left a comment
There was a problem hiding this comment.
Isn't this a kludge? We should find and fix the root cause.
I think this is the proper fix. Without this Furthermoe, |
-State aggregate function combinatorsrunningAccumulate with nested states
|
@groeneai investigate the failures |
|
@antaljanosbenjamin — quick summary, then details. CI failures: chronic infra, not PR-caused. Only two checks failed:
CIDB cross-PR over 30 days (
Zero master signal, broad cross-PR scatter — these are the well-known "server cannot start under stress" infra flakes. Nothing in your diff is plausibly related to server startup. The bot's I applied your patch on top of master, built, and ran: CREATE TABLE t_state_merge
(k UInt32, s AggregateFunction(sumStateMerge, AggregateFunction(sum, UInt64)))
ENGINE = MergeTree ORDER BY k;
INSERT INTO t_state_merge
SELECT k, sumStateMergeState(s) FROM t_sum_state GROUP BY k;
SELECT runningAccumulate(s) FROM t_state_merge;With the patch applied: On master (no patch) the same query returns a (UAF-tainted) Scope of the regression. It only reproduces when the column itself has stored type Why it happens.
Suggested fix. Add a delegating override to void insertMergeResultInto(AggregateDataPtr __restrict place, IColumn & to, Arena * arena) const override
{
nested_func->insertMergeResultInto(place, to, arena);
}For I built and tested this on top of your patch:
The same override probably also helps Optional: a small regression test that creates a stored Related. This PR also fixes STID Local repro session: |
When `runningAccumulate` is invoked on a column whose attached aggregate function is a `Merge` wrapper over a state-returning nested function (e.g. a column of type `AggregateFunction(sumStateMerge, ...)`), `AggregateFunctionMerge::isState` reports `true` because it is propagated from the nested function. The PR's `runningAccumulate` then takes the `insertMergeResultInto` branch — but `AggregateFunctionMerge` had no override, so the base `IAggregateFunction::insertMergeResultInto` would throw `NOT_IMPLEMENTED` for any function that advertises `isState`. Add the override to delegate to `nested_func->insertMergeResultInto`, matching how every other state-propagating combinator (`ForEach`/`OrFill`/`If`/`Array`/...) already routes the call. Extend the regression test in `tests/queries/0_stateless/04218_running_accumulate_state_uaf.sql` to cover this path via a `CAST` to `AggregateFunction(sumStateMerge, ...)`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 13/13 (100.00%) | Lost baseline coverage: none · Uncovered code |
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Fixes a use-after-free in runningAccumulate when called on a column whose aggregate function returns its own state (e.g. uniqStateOrDefaultState, sumStateOrDefaultState, uniqStateForEachState).
Note
Medium Risk
Changes how
runningAccumulatematerializes results for state-returning aggregate functions and altersMergecombinator behavior, which can affect query results and previously failing code paths forAggregateFunctionstate columns.Overview
Fixes
runningAccumulatefor aggregate functions that return their own state: it now usesinsertMergeResultInto(instead ofinsertResultInto) whenagg_func.isState()is true, preventing aliasing of the stack-local accumulator and a use-after-free inColumnAggregateFunctionresults.Adds an
AggregateFunctionMerge::insertMergeResultIntooverride to delegate through combinator chains (e.g.sumStateMerge) instead of hitting the baseNOT_IMPLEMENTEDpath, and introduces a stateless regression test (04218_running_accumulate_state_uaf) covering-Stateplus combinators like-OrDefault,-ForEach, and-Merge.Reviewed by Cursor Bugbot for commit 3d7ce6e. Bugbot is set up for automated code reviews on this repo. Configure here.