Support per-element aggregation of Tuple columns in SummingMergeTree, AggregatingMergeTree and CoalescingMergeTree#98039
Conversation
|
Workflow [PR], commit [fe61ffb] Summary: ✅
AI ReviewSummaryThis PR adds opt-in recursive Findings❌ Blockers
Tests
Final VerdictStatus: ❌ Block Minimum required action: fix the |
c5f285a to
661b6bd
Compare
661b6bd to
7a3c9de
Compare
fix flatten bug optimize code optimize test cases optimize test cases optimize settings optimize comment optimize code review issue optimize code review issue # Conflicts: # src/Storages/MergeTree/MergeTreeData.cpp optimize review code fix bug fix review bug fix review bug
3e6351c to
bf9176f
Compare
nihalzp
left a comment
There was a problem hiding this comment.
Thanks for working on this!
I was trying this query but it does not sum:
CREATE TABLE t (key UInt32, value Tuple(a UInt64, b UInt64))
ENGINE = SummingMergeTree(value) ORDER BY key
SETTINGS allow_tuple_element_aggregation = 1;
INSERT INTO t VALUES (1, (10, 20));
INSERT INTO t VALUES (1, (30, 40));
OPTIMIZE TABLE t FINAL;
SELECT * FROM t;1 (10,20)
|
The Stress test (arm_msan) failure is fixed by #101239, which should be merged first. After it is merged, please update the branch to include the fix. |
Thank you very much for pointing out this issue. The root cause was that, after the tuple was flattened, the resulting names could not be matched against the source column names recorded in |
add coalescing table test cases flatten column_names_to_sum fix code space
|
|
||
| static AggregatingSortedAlgorithm::ColumnsDefinition defineColumns( | ||
| const Block & header, const SortDescription & description) | ||
| const Block & header, const SortDescription & description, bool allow_tuple_element_aggregation) |
There was a problem hiding this comment.
AggregatingSortedAlgorithm now flattens tuple leaves and aggregates every AggregateFunction / SimpleAggregateFunction leaf that is not in the sorting key, but it still has no visibility into PARTITION BY required columns. Unlike the SummingMergeTree and CoalescingMergeTree paths, the AggregatingMergeTree call sites do not pass metadata.getPartitionKey().expression->getRequiredColumns, so an opt-in table can use a tuple leaf such as metrics.part SimpleAggregateFunction(sum, UInt64) in PARTITION BY metrics.part and ORDER BY id; merging rows in that partition will aggregate metrics.part from 10 to 20 while the part still belongs to partition 10 (partition id and minmax are computed before merge-on-insert too). Please pass partition+sorting required columns into AggregatingSortedAlgorithm, mark matching leaves or ancestors as column_numbers_not_to_aggregate, and add a regression covering FINAL and OPTIMIZE.
There was a problem hiding this comment.
This is an existing issue/bug so out of scope for this PR.
CREATE TABLE t (id UInt64, part SimpleAggregateFunction(sum, UInt64))
ENGINE = AggregatingMergeTree PARTITION BY part ORDER BY id;
INSERT INTO t VALUES (1, 10);
INSERT INTO t VALUES (1, 10);
OPTIMIZE TABLE t FINAL;
SELECT * FROM t; -- 1 20; partition column summed
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 387/401 (96.51%) | Lost baseline coverage (was covered on master, now uncovered in this PR): 3 line(s) · Uncovered code |
3376a37
…use#101937) Cover the exact ClickHouse#101937 reproducer: a CoalescingMergeTree with the canonical .key/.value nested subcolumns (Array(String) key, Array(UInt32) value) merged at query time via SELECT ... FINAL. This is a distinct branch from the existing .id/.val OPTIMIZE FINAL case in the same test. Verified bidirectionally: with the old *Map name-suffix special-casing in SummingSortedAlgorithm::defineColumns reinstated the SELECT FINAL aborts with Assertion 'px != 0' failed (null ColumnPtr); on current master it returns the coalesced last value. The crash itself was fixed on master by ClickHouse#98039. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Add a new immutable
MergeTreesettingallow_tuple_element_aggregation, disabled by default. When enabled,SummingMergeTree,AggregatingMergeTreeandCoalescingMergeTreerecursively flattenTuplecolumns and aggregate each leaf element independently during merges, exactly as if it were a top-level column —SummingMergeTreesums it,AggregatingMergeTreemerges its aggregate-function state, andCoalescingMergeTreekeeps its last non-NULL value. The setting must be specified at table creation time and is silently ignored by engines that do not support it.Example:
Subcolumn
data.valwill be summed during merges, just as a top-level SimpleAggregateFunction column would be.Note
Medium Risk
Changes core MergeTree merge algorithms to optionally flatten/reconstruct Tuple columns during merges, which can affect aggregation correctness and column ordering if edge cases slip through. Risk is mitigated by being gated behind a new immutable table setting and covered by new stateless tests.
Overview
Adds a new immutable MergeTree table setting
allow_tuple_element_aggregation(default off) that enables recursive aggregation ofTupleleaf elements forSummingMergeTree,AggregatingMergeTree, andCoalescingMergeTreeduring merges.When enabled, merge algorithms now flatten tuple columns (including unnamed and nested tuples, and materializing
ColumnConsttuples) before selecting/processing aggregate columns, then reconstruct the original tuple structure after merging; the pipeline is plumbed throughReadFromMergeTree,MergeTask, andMergeTreeDataWriter. The PR also validates configuration by rejecting unsupported engines and disallowing plainTuplecolumns in the sorting key under this mode, and updatesColumnAggregateFunction::isDefaultAtto returnfalseinstead of throwing.Includes extensive new stateless tests covering
SimpleAggregateFunction/AggregateFunctiontuple elements, nested/unnamed tuples, overflow, and prior column-indexing edge cases.Written by Cursor Bugbot for commit 71792f7. This will update automatically on new commits. Configure here.
Version info
26.6.1.628