Skip to content

feat(snuba): Add FUNCTION_COLLECT_UNIQUE for array-returning aggregations - #393

Merged
pbhandari merged 2 commits into
mainfrom
feat/collect-unique-aggregation
Aug 10, 2026
Merged

feat(snuba): Add FUNCTION_COLLECT_UNIQUE for array-returning aggregations#393
pbhandari merged 2 commits into
mainfrom
feat/collect-unique-aggregation

Conversation

@pbhandari

Copy link
Copy Markdown
Contributor

Summary

Adds FUNCTION_COLLECT_UNIQUE = 14 to the snuba Function enum in trace_item_attribute.proto. Unlike the existing aggregations that reduce a group to a scalar, this one collects each group's distinct values into an array (backed by ClickHouse groupUniqArray) and is returned as a val_array on TraceItemTable.

Includes the regenerated Rust bindings and Cargo.lock bump per the repo's codegen workflow.

Related

🤖 Generated with Claude Code

@pbhandari
pbhandari requested a review from a team as a code owner August 3, 2026 19:43
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow ci / buf-checks (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedAug 10, 2026, 2:40 PM

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3f587fb. Configure here.

Comment thread Cargo.lock Outdated
Comment thread proto/sentry_protos/snuba/v1/trace_item_attribute.proto
@pbhandari
pbhandari force-pushed the feat/collect-unique-aggregation branch from 3f587fb to 2be3151 Compare August 6, 2026 16:11
@pbhandari
pbhandari merged commit 6e1a8a5 into main Aug 10, 2026
23 of 30 checks passed
pbhandari added a commit to getsentry/snuba that referenced this pull request Aug 10, 2026
…temTable (#8256)

## Summary

Adds support for `FUNCTION_COLLECT_UNIQUE` in the TraceItemTable
endpoint. Unlike every other aggregation — which reduces a group to a
single scalar — this one gathers each group's distinct scalar values
into an array, returned as a `val_array` in the response. It maps to
ClickHouse's `groupUniqArray`.

## Related

- Linear: [EAP-623 — Array aggregation support for
GetTraceItemTable](https://linear.app/getsentry/issue/EAP-623/array-aggregation-support-for-gettraceitemtable)
- Proto PR (adds the `FUNCTION_COLLECT_UNIQUE` enum value this
consumes): getsentry/sentry-protos#393

## Changes

**Aggregation expression (`aggregation.py`)**
- Map `FUNCTION_COLLECT_UNIQUE` to `groupUniqArrayIf(max_array_size)`,
in both the plain and `FUNCTION_ANY`-style non-rounded branches (the
result is an array, so `round()` must not be applied).
- Reject extrapolation for `FUNCTION_COLLECT_UNIQUE`: scaling a set of
values by a sampling weight is meaningless, so
`get_extrapolated_function` raises `BadSnubaRPCRequestException` rather
than silently producing a nonsensical result.
- Refactored `get_extrapolated_function` to hoist the shared `condition`
and `rounded_sampling_weight` sub-expressions out of the per-function
map, removing the repeated inline `and_cond(...)` / cast boilerplate.

**Response conversion (`trace_item_table.py`)**
- New `_get_aggregate_converter` centralizes the aggregate-result →
`AttributeValue` mapping: `FUNCTION_COLLECT_UNIQUE` → array converter,
`FUNCTION_ANY` → key-typed converter, everything else → double. Replaces
the duplicated `FUNCTION_ANY` special-casing across the `aggregation`
and `conditional_aggregation` branches.

**Config (`schema.json`)**
- New `snuba_query_max_array_size` option (default 1000). Bounds how
many distinct values `groupUniqArray` accumulates per group. Unlike
`uniq`, `groupUniqArray` holds every distinct value on the aggregating
node, so this caps its memory footprint; a group exceeding the limit is
truncated rather than allowed to grow unbounded.

## Tests

- `test_aggregation.py`: `FUNCTION_COLLECT_UNIQUE` is rejected under
every extrapolation mode, and produces a `groupUniqArrayIf` expression
when extrapolation is off.
- `test_endpoint_trace_item_table.py`: end-to-end coverage for the
aggregation (returns `val_array` per group) and for the
conditional-aggregation variant (collects distinct values of one column
filtered on another).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown

EAP-623

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants