You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bbabcc6
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: .changeset/21417-analytics-faces-one-lowering.md
+10-4Lines changed: 10 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,13 +2,13 @@
2
2
"@objectstack/service-analytics": minor
3
3
---
4
4
5
-
fix(service-analytics)!: the analytics read scope and the `where` tree compile the shared lowering's bound and NULL guards; their own whole-day and NULL-polarity copies are deleted (ADR-0053 D-D1 items 7 to 9)
5
+
fix(service-analytics)!: the analytics read scope, the `where` tree and the draft preview take the shared lowering's bound and NULL guards; their own whole-day and NULL-polarity copies are deleted (ADR-0053 D-D1 items 7 to 9)
6
6
7
7
Clause-②: no (narrowing)
8
8
9
-
<!-- adr-0087: not-required (no-migration-prescription) a change of how the native analytics strategy answers an ordering comparison on a column its host declares neither datetime nor date, not of anything an author writes: no spec key, spelling, export or stored shape moves. AnalyticsQuerySchema, CubeSchema, DatasetSchema and every RLS policy parse and save as before, the package index exports the same names with the same types, and no stored row is read or rewritten. What moves is the row set a bare-day upper bound selects on such a column, which now equals the engine's own answer for the same filter, so there is nothing for objectstack migrate meta to rewrite. The other categories are closed on facts: the package publishes (not unpublished); no ADR-0087 id covers a filter's bound semantics and this diff adds none (not registered / already-registered); and the change is runtime behaviour, not a declaration (not runtime-interface-only / type-surface-only). -->
9
+
<!-- adr-0087: not-required (no-migration-prescription) a change of how the native analytics strategy and the draft preview answer an ordering comparison on a column its host declares neither datetime nor date, and of how the draft preview reads a window end, not of anything an author writes: no spec key, spelling, export or stored shape moves. AnalyticsQuerySchema, CubeSchema, DatasetSchema and every RLS policy parse and save as before, the package index exports the same names with the same types, and no stored row is read or rewritten. What moves is the row set a bare-day upper bound selects on such a column, which now equals the engine's own answer for the same filter, and the row set the draft preview selects for a window, which now equals what it selects for the same bounds written as a where; so there is nothing for objectstack migrate meta to rewrite. The other categories are closed on facts: the package publishes (not unpublished); no ADR-0087 id covers a filter's bound semantics and this diff adds none (not registered / already-registered); and the change is runtime behaviour, not a declaration (not runtime-interface-only / type-surface-only). -->
10
10
11
-
**BREAKING**: this narrows the rows the native analytics strategy selects for a bare-day upper bound on a column the host declares as neither `datetime` nor `date` — a `text` column, for example. It ships as `minor` under the launch-window convention for answer narrowings. No export, published type, accepted input or error code changes.
11
+
**BREAKING**: this narrows the rows the native analytics strategy and the draft preview (`queryDataset` with `previewDrafts`) select for a bare-day upper bound on a column the host declares as neither `datetime` nor `date` — a `text` column, for example. It ships as `minor` under the launch-window convention for answer narrowings. No export, published type, accepted input or error code changes.
12
12
13
13
**What is deleted.** The native SQL strategy no longer reads a bare `YYYY-MM-DD``$lte`, a `$between` maximum or an explicit `dateRange` end as "through that whole day" on every column, and no longer drops such a bound on `9999-12-31` whatever the column holds. The whole-day rule is applied once, by the shared `lowerFilterCondition` (`@objectstack/spec/data`), with the column's declared type, the reader the plugin already wires from the engine's registry (`sourceFieldMeta`): a declared `datetime` column keeps the whole day, and every other declared column is compared as written, as the engine compares it. The `/analytics/sql` echo renders the same lowering.
14
14
@@ -24,4 +24,10 @@ On a declared `datetime` or `date` column every answer is unchanged, on both str
24
24
25
25
**The `/analytics/sql` echo.** A `dateRange` window on a declared `date` column now prints the inclusive `<=` the engine runs, where it printed `<` the next day; on a column the host names no type for, it prints the bound the ObjectQL strategy hands the engine, as written. A preset window that stops before its end (`today`, `this_month`, …) now prints `<` its end instant with that instant bound, where it printed `<=` with no value bound. The NULL guards print once where they printed two or three nested copies of the same guard; every row set is unchanged.
26
26
27
-
**Unchanged.** Every answer on a declared `datetime` or `date` column, on the native and the ObjectQL strategy; every answer of the ObjectQL strategy; every answer of the read scope; and the draft preview, which keeps its own bound until its typed reader is wired.
27
+
**The draft preview now agrees with the engine too.**`queryDataset` with `previewDrafts` evaluates drafted seed rows in memory; it kept its own whole-day copy, read on every column. It now hands the evaluator the drafted object's declared types (`sourceFieldMeta`), and the shared lowering applies the rule with them: a declared `datetime` column keeps the whole day, any other declared column is compared as written, and a column the host names no type for is read type-blind (ADR-0053 D-D1 item 7). Measured through the plugin's own composition over the same rows, the preview's `note` cells above moved onto the engine's answer exactly as the native face's did (`$lte` a day 3 to 2, `$between` and a window of one day 2 to 1, the `$not` gaining the row). Every `datetime` and `date` cell is unchanged.
28
+
29
+
- A preview window is now the `{ $gte, $lte }` pair the ObjectQL strategy hands the engine, matched like the same bounds in a `where`. Its end used to be read with a `'~'` suffix ("that instant and its own sub-values"), a reading no other face gives. Measured on a `datetime` column over SQLite, a canonical end (`…T10:00:00.000Z`) answers as before and as the engine. An end spelled shorter than the stored value is compared as text, as the preview's `where` already compared it: an end of `…T10:00` or `…T10:00:00` now leaves out the row stored at exactly that instant (the engine keeps it), and leaves out the rows inside that minute or second (the engine leaves them out too; the old reading kept them). Write a window end in full (`2026-07-28T10:00:00.000Z`) to get the engine's rows on the preview.
30
+
- A window over rows that hold a `Date` (the BSON storage form a MongoDB-backed draft reads back) is compared as instants, like the preview's `where`; it was compared as the `Date`'s display text.
31
+
- A host that wires no `sourceFieldMeta` (or an object the registry does not hold yet) reads every column type-blind. On a `text` column holding a value that sorts above `'9999-12-31'` (`'n'`), a `$lte` or `$between` maximum of `9999-12-31` now keeps that row, as every other type-blind seam does; the deleted copy left it out.
32
+
33
+
**Unchanged.** Every answer on a declared `datetime` or `date` column, on the native strategy, the ObjectQL strategy and the draft preview; every answer of the ObjectQL strategy; every answer of the read scope.
0 commit comments