Skip to content

Commit 112a8c6

Browse files
os-warrenclaude
andauthored
fix(service-analytics): apply the dataset-level filter on the ObjectQL path (#10413 phase 1) (#10758)
`ObjectQLStrategy.execute` built its engine filter from `normalizeAnalyticsFilterTree(query)` alone — the caller's `where` and the time windows — and consulted the dataset registry nowhere. On a deployment whose driver reports `objectqlAggregate` but not `nativeSql`, `engine.aggregate` was therefore called with no `filter` key at all: the dataset's definition-level scope was dropped and every measure aggregated the whole table, while the dashboard door answered the scoped numbers for the same cube. The scope now travels as its own `$and` conjunct — never a key merge, for the reason `withReadScope` states: the caller's `where` and the dataset scope can name the same field. The representative SQL echo renders it as well, on the #3601/#3602 rule that an echo omitting an applied predicate is the same lie as one inventing a predicate. Phase 1 only: per-measure filters cannot be expressed against an aggregation typed `{ field, method, alias }`. That contract widening is #10576 and the lowering is phase 2 — pinned open, wrong numbers and all, in `objectql-dataset-filter.test.ts`. Part of #10413 Claude-Session: https://claude.ai/code/session_01PnJHU45vPJj5UQrxe946Bx Co-authored-by: Claude <noreply@anthropic.com>
1 parent b05a543 commit 112a8c6

3 files changed

Lines changed: 480 additions & 1 deletion

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
"@objectstack/service-analytics": patch
3+
---
4+
5+
Apply a dataset's definition-level `filter` on the ObjectQL analytics path
6+
(#10413, phase 1). `/api/v1/analytics/query` served by a driver that reports
7+
`objectqlAggregate` but not `nativeSql` (MongoDB, the memory driver) reached
8+
`engine.aggregate` with no `filter` key at all: the dataset's own scope — a
9+
`filter: { is_deleted: false }` on the dataset definition — was dropped, so
10+
every measure aggregated the whole table while the dashboard door, on the same
11+
cube and the same measure names, answered the scoped numbers. The scope is now
12+
ANDed into the strategy's whole-call filter (never merged key-by-key, so a
13+
caller's own `where` and the time windows cannot be overwritten by it), and the
14+
representative SQL echo renders it too.
15+
16+
Per-MEASURE `filter`s on this path are still not applied: an
17+
`engine.aggregate` aggregation is `{ field, method, alias }` and cannot carry a
18+
predicate of its own. Widening that contract is #10576; lowering the measure
19+
filters into it is phase 2 of #10413. The native-SQL path already applies both
20+
(#10298).

0 commit comments

Comments
 (0)