From 2cd3d6f487219be21148d19dbb23e176efe71ad3 Mon Sep 17 00:00:00 2001 From: Chris Eubank <108756251+christianeu-db@users.noreply.github.com> Date: Fri, 11 Sep 2026 18:41:07 +0000 Subject: [PATCH 1/2] feat(core-spec): add FILTER (WHERE ...) aggregate modifier Define the SQL-standard FILTER (WHERE ) postfix modifier on aggregate expressions in the Conditional Aggregations (REQUIRED) section of core-spec/expression_language.md. The clause has SQL:2003 semantics (optional feature T612): the aggregate is computed over only the rows where the predicate is TRUE, with the aggregate's own empty-input value when no row matches. The change is additive and backward compatible. It adds no schema node and no field to Metric, Field, or Dataset; the existing CASE form stays valid. The predicate MUST reference only fields of the same dataset as the aggregate's arguments. Clarifies that FILTER (WHERE ...) is an aggregate modifier, distinct from the unsupported standalone WHERE clause. Co-authored-by: Isaac --- core-spec/expression_language.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core-spec/expression_language.md b/core-spec/expression_language.md index 617aeefd..800e6cc5 100644 --- a/core-spec/expression_language.md +++ b/core-spec/expression_language.md @@ -217,7 +217,7 @@ APPROX_PERCENTILE(response_time, 0.95) ### Conditional Aggregations (REQUIRED) SUM / COUNT aggregation functions support `DISTINCT.` -All aggregations should support filtered aggregation: +All aggregations must support filtered aggregation, expressed either with a `CASE` argument or with a postfix `FILTER (WHERE ...)` modifier: ```sql -- DISTINCT modifier @@ -227,7 +227,25 @@ COUNT(DISTINCT customer_id) -- Filtered aggregation via CASE SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END) COUNT(CASE WHEN status = 'completed' THEN 1 END) + +-- Filtered aggregation via FILTER (WHERE ...) +SUM(amount) FILTER (WHERE status = 'completed') +COUNT(*) FILTER (WHERE status = 'completed') +``` + +#### `FILTER (WHERE ...)` (REQUIRED) + +Every aggregate function must support a postfix `FILTER (WHERE )` modifier: + ``` +() FILTER (WHERE ) +``` + +The clause has the semantics of the SQL:2003 `` (optional feature T612): the aggregate considers only the rows for which `` is `TRUE`. + +`FILTER (WHERE ...)` is a modifier on an aggregate expression. It is not the standalone `WHERE` clause listed under [Not Supported in Expressions](#not-supported-in-expressions). The `` must reference only fields of the same dataset as the aggregate's arguments. + +Engines without native `FILTER (WHERE ...)` support MAY lower it to the equivalent `CASE` form. ### Decomposability Reference From 8380cb1dbef2fbc5bde5ff1d4dbe058f5c552702 Mon Sep 17 00:00:00 2001 From: Chris Eubank <108756251+christianeu-db@users.noreply.github.com> Date: Sat, 12 Sep 2026 06:04:14 +0000 Subject: [PATCH 2/2] docs(core-spec): respond to @kayemkim's feedback on FILTER (WHERE) - State that FILTER is applied to the aggregate's input, not a query WHERE, so it never removes output groups. - Add two CASE-lowering examples (value aggregate and COUNT(*)). - Soften " is TRUE" to " succeeds" so engines with truthy (non-strict-TRUE) evaluation are covered. Co-authored-by: Isaac --- core-spec/expression_language.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core-spec/expression_language.md b/core-spec/expression_language.md index 800e6cc5..74cdaeed 100644 --- a/core-spec/expression_language.md +++ b/core-spec/expression_language.md @@ -241,11 +241,19 @@ Every aggregate function must support a postfix `FILTER (WHERE )` mod () FILTER (WHERE ) ``` -The clause has the semantics of the SQL:2003 `` (optional feature T612): the aggregate considers only the rows for which `` is `TRUE`. +The clause has the semantics of the SQL:2003 `` (optional feature T612): the aggregate considers only the rows for which `` succeeds. `FILTER` is applied to the aggregate's input, not as a query `WHERE`, so it never removes output groups. `FILTER (WHERE ...)` is a modifier on an aggregate expression. It is not the standalone `WHERE` clause listed under [Not Supported in Expressions](#not-supported-in-expressions). The `` must reference only fields of the same dataset as the aggregate's arguments. -Engines without native `FILTER (WHERE ...)` support MAY lower it to the equivalent `CASE` form. +Engines without native `FILTER (WHERE ...)` support MAY lower it to the equivalent `CASE` form: + +```sql +-- value aggregate: filter the argument +SUM(amount) FILTER (WHERE status = 'completed') --> SUM(CASE WHEN status = 'completed' THEN amount END) + +-- COUNT(*): filter a constant +COUNT(*) FILTER (WHERE status = 'completed') --> COUNT(CASE WHEN status = 'completed' THEN 1 END) +``` ### Decomposability Reference