Conversation
zzylol
added a commit
that referenced
this pull request
Oct 4, 2026
Plan the filtered-aggregate integration test with the executor's capability set, as #609 does for the other integration tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 4, 2026
An Aggregate with per-measure filters (SQL FILTER, or the IS NOT NULL a COUNT(nullable) implies) and a SummaryAgg with a filter both failed to bind. Rows that fail the filter now update nothing, but every group is kept: a group with no matching row reads 0 for COUNT and NULL for SUM/AVG/MIN/MAX and, through an empty KLL or DDSketch, for a quantile. A filtered quantile measure is now declared nullable, like SUM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zzylol
force-pushed
the
stack/509-y2-filtered-aggregates
branch
from
October 5, 2026 06:21
4c68af1 to
e1a4e6d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack: Wave 3 chain: #605 → #607 → #608 → #609 → #610
Rebased on main d4869a7 (DF 54).
Stack: … → #605 → this PR → (Pass 1 filtered aggregates, next)
Why
Part of #509 and #580 (J, filtered aggregates); Q47 (a). The executor could not run any filtered aggregate. A per-measure filter on
Aggregateand aSummaryAgg.filterwere both rejected at binding, so even the exact plan forCOUNT(*) FILTER (WHERE …)failed. This also coveredCOUNT(y)over a nullabley, which the SQL frontend lowers as a count filtered byy IS NOT NULL. #605 (item "Not in this PR") left filtered counts to this work.What
events(g, x)with rows a: 1, -1, 2; b: -3, 0; c: 5:plan_stages+ executor)SELECT g, COUNT(*) FILTER (WHERE x > 0) … GROUP BY gfiltered aggregate has no native implementationSELECT g, SUM(x) FILTER (WHERE x > 0) … GROUP BY gSELECT g, COUNT(y) … GROUP BY g(nullabley)yper group, b 0SummaryAggwithfilter(exactCount, KLL)filtered summary update has no native implementationEmpty groups follow SQL. A group is formed from all of its rows, and the filter only decides which rows update the measure. A group with no matching row therefore still appears. COUNT (and distinct count) reads 0. SUM, AVG, MIN, MAX and a quantile read NULL. HAVING is unaffected: the SQL frontend lowers it to a
Filterabove the aggregate. PromQL never emits per-measure filters, since label matchers are scan predicates.How
Aggregategains per-measurefilters(with_measure_filters). A filtered SUM/AVG/MIN/MAX output becomes nullable. The three summary builds (per-group, keyed, shared Hydra) gain an optional rowfilter(with_row_filter). A row passes only when the predicate istrue; NULL drops it, as in SQL. Both fields are omitted from serialization when absent, so existing plans are unchanged. Deserialization rebuilds and checks them.physical_plannercompiles the predicates against the input schema. The unfilteredSummaryAgglowering moved, unchanged, intosummary_buildso that the filter is applied in one place. Ingestion-time precompute still rejects a filteredSummaryAgg, because its raw-sample input has no SQL columns to evaluate the filter against.AggregateCore::is_empty(KLL, DDSketch). A sketch evaluation with a nullable result reads NULL for an empty state. An empty KLL quantile is now an error, not 0.0, as DDSketch's already was.Quantilemeasure is declared nullable, matching SUM.Tests
These failed on #605 with the errors above:
filtered_aggregates::exact_filtered_count_keeps_groups_without_matches,exact_filtered_sum_is_null_for_groups_without_matches,exact_count_of_nullable_column_skips_nulls: SQL →plan_stages→ executor, with a group that has no matching row.filtered_aggregates::hand_filtered_exact_count_compiles_and_executes,hand_filtered_kll_compiles_and_executes: Pass 1's unfilteredCount/ KLL alternatives withSummaryAgg.filterset by hand, compiled and executed.New executor tests:
physical_semantics::measure_filters_keep_groups_without_matching_rows: filtered and unfiltered measures side by side, a NULL predicate, nullability, and a serde round trip.physical_semantics::filtered_summary_build_keeps_empty_groups: a filtered KLL build, where the empty group reads NULL, plus a serde round trip.Gates
cargo fmt --all --check,cargo clippy --workspace --all-targets --all-features -- -D warnings: pass.cargo test --workspace: 1,649 passed, 23 ignored (feat(planner): Pass 1 offers HydraCms for grouped approximate counts #605: 1,642 / 23; +7).tools/dag-viewer): 29 ran, 6 skipped.Not in this PR
Refs #509, #580, #605.
🤖 Generated with Claude Code