Commit 7bb7830
committed
feat(analytics): honour widget dateGranularity, sortBy/sortOrder, and limit in dataset queries (#3588)
Three presentation options were accepted by the metadata layer and then dropped
by the analytics query builder — no SQL, no error. The only symptom was the
`sql` a dataset response echoes, so a dashboard could declare
`dateGranularity: 'month'` and quietly render one bar per record.
- `DatasetSelection.dateGranularity` buckets every selected date dimension.
Precedence per dimension: an explicit `timeDimensions` granularity, then the
selection's, then the dataset dimension's own default — so a widget can bucket
a trend by month without the dataset committing every consumer to it.
- `order`/`limit`/`offset` are applied to the ASSEMBLED grid: after
measure-scoped sub-queries merge, after `compareTo` columns attach, and after
derived measures are computed. A derived measure is therefore a valid sort
key, and the ObjectQL aggregate path — which has no ordering grammar, and
which native SQL hands every date-bucketed query to — orders identically to
native SQL. A single-query selection still pushes the window into the
statement. An order key naming nothing the selection projects is rejected
(400) rather than ignored.
- A `limit` without an `order` orders by the selected dimensions first, so it
truncates a reproducible window instead of an arbitrary subset.
- The four query-affecting widget `options` keys plus `stageOrder` are declared
on `DashboardWidgetOptionsSchema`, making a typo an author-time error. The bag
stays open, so renderer extras pass through untouched.
Two latent bugs surfaced while fixing the above:
- `order`/`limit` were forwarded to EVERY sub-query. A measure-scoped
supplementary query selects one measure, so an inherited ORDER BY named a
column it never selected and an inherited LIMIT truncated it before the merge,
dropping rows from the grid. Nothing hit this only because nothing passed
`order`.
- The `compareTo` pass hand-built its query and skipped granularity resolution,
merging a month-bucketed primary grid against raw-timestamp comparison rows.
No dimension key matched, so every `<measure>__compare` column came back
empty.
`ObjectQLStrategy` now also echoes a representative `sql` (date_trunc, WHERE,
ORDER BY, LIMIT; filter values parameterized, never inlined). The `sql` field
previously vanished whenever a query was date-bucketed, leaving an author unable
to tell "not implemented" from "this strategy doesn't report".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEZLBGyNoJMLvtGPqsMPRC1 parent 6ba3788 commit 7bb7830
8 files changed
Lines changed: 826 additions & 30 deletions
File tree
- .changeset
- packages
- rest/src
- services/service-analytics/src
- __tests__
- strategies
- spec
- src
- contracts
- ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5260 | 5260 | | |
5261 | 5261 | | |
5262 | 5262 | | |
5263 | | - | |
| 5263 | + | |
5264 | 5264 | | |
5265 | 5265 | | |
5266 | 5266 | | |
| |||
0 commit comments