Repository navigation
Commit fed0db8
docs(data): count_distinct is lowered on the SQL family; state the real limit (#21085)
Fixes #21039
Clause-②: no
## What this changes
Docs only, two hand-written pages. Both said the SQL drivers refuse
`count_distinct` with `501 NOT_IMPLEMENTED` and that its SQL lowering is
"scheduled". It has been lowered since #6409; both callouts now state
what `main` does.
## Before / after
| page | before | after |
|:--|:--|:--|
| `content/docs/data-modeling/queries.mdx` (warn callout under the
function table) | "`count_distinct` is not yet lowered by the SQL
drivers ... refuse it as a capability gap, `501 NOT_IMPLEMENTED` ... its
SQL lowering is scheduled" | Computed on every backend: SQL drivers
(SqlDriver, both Turso transports) lower it to `COUNT(DISTINCT field)`;
MongoDB, the in-memory driver and the engine's in-memory fallback count
distinct non-null values; no `field` is `400 INVALID_QUERY`. The one
real limit: a JSON-stored field (structured-JSON types, `multiselect` /
`checkboxes` / `tags`, or `multiple: true`) is `400 INVALID_FIELD` at
the engine before any driver runs. One sentence on the merged #21037
effect (min / max / avg over a refused type answer the same `400
INVALID_FIELD`). |
| `content/docs/protocol/objectql/query-syntax.mdx` (callout after
"Schema enum", old lines 971-982) | "Only count, sum, avg, min, max are
portable today. count_distinct ... not yet by the SQL drivers ... 501
... Its SQL lowering is scheduled" | All six functions computed on every
backend, same backend list, `median` still `400 INVALID_QUERY`, same
JSON-stored limit. Callout type warn to info. This also removes the
page's self-contradiction with its own line 118 (`COUNT(DISTINCT field)`
on both SQL faces since #6409). |
## Code anchors (origin/main a75311d)
- SQL lowering table:
`packages/drivers/driver-sql/src/sql-driver.ts:1524`
(`['count_distinct', { sql: 'count', distinct: true }]`); emission
`:10252-10254` (`count(distinct ??)`); fieldless refusal `:10222`
calling `refuseDistinctAggregateWithoutField` (`:1827`, `INVALID_QUERY`
/ 400).
- Turso remote transport:
`packages/drivers/driver-turso/src/remote-transport.ts:677` and `:1408`.
Local Turso `extends SqlDriver` (`turso-driver.ts:631`).
- Memory driver:
`packages/drivers/driver-memory/src/memory-driver.ts:2164` (null and
undefined excluded). Engine in-memory fallback:
`packages/objectql/src/in-memory-aggregation.ts:234`. MongoDB:
`packages/drivers/driver-mongodb/src/mongodb-aggregation.ts:406`.
- Engine refusal:
`packages/objectql/src/aggregate-field-type-door.ts:236`
(`assertAggregationFieldTypesAccepted`; `INVALID_FIELD` at `:261`,
status 400 at `:262`), called at
`packages/objectql/src/engine.ts:16891`. Table row:
`packages/spec/src/data/aggregate-field-type-compatibility.ts:214`
(`count_distinct: DISTINCT_COMPARABLE_FIELD_TYPES`; JSON-stored list
`:190-196`).
- Pins:
`packages/objectql/src/engine-json-stored-group-distinct-door.test.ts:189`;
`packages/rest/src/data-json-stored-group-distinct-door.test.ts:219`
(read; its SQLite cell always runs, PostgreSQL / MySQL cells are skips
without `OS_TEST_POSTGRES_URL` / `OS_TEST_MYSQL_URL`).
- #21037 at write time: MERGED (2026-10-01T04:51:07Z, head 9497f4c).
Its `aggregate-field-type-door.ts` is on this base, so the one sentence
about min / max / avg is true on main.
- Not run locally: the pins above (docs-only change; the claims are read
from the code and the pin files, not re-executed).
## Census of hand-written pages mentioning `count_distinct`
- `data-modeling/queries.mdx`: stale, fixed here.
- `protocol/objectql/query-syntax.mdx`: stale at the callout, fixed
here; lines 104, 118, 134 and 1067 current (118 states the lowering
correctly; 134 is the interface union; 1067 points to the aggregation).
- `ai/natural-language-queries.mdx` (lines 18, 27): current. Lists
`count_distinct` among the `aggregate_records` functions, which the tool
declares (`packages/mcp/src/mcp-http-tools.ts:821`); no capability
claim.
- `api/data-api.mdx` (line 418): current. The `_count_distinct` measure
suffix is the one the analytics service names
(`packages/services/service-analytics/src/analytics-service.ts:2882`).
- `deployment/validating-metadata.mdx` (lines 210-213): current. States
exactly the table row: every type except the structured-JSON types and
`multiselect` / `checkboxes` / `tags`
(`aggregate-field-type-compatibility.ts:190-214`).
- `kernel/contracts/data-engine.mdx` (lines 152, 498, 509): current.
"every face computes" holds for the vocabulary on all backends above;
the JSON-stored limit is a field-type refusal, not a face gap.
- `ui/dashboards.mdx` (line 328): current. Function table row, no
capability claim.
- `content/docs/references/**` and `content/docs/releases/**`: not
touched.
## Gates
`node scripts/pm/dispatch-gates.mjs --commands`: 40 derived; `--ran`
reports 40 run, 0 NOT-MEASURED, 0 UNRUN. Five gates (two in
`@objectstack/lint`, `check:skill-examples`,
`check:docs-transcript-drift`) first answered exit 3 PREREQUISITE NOT
MET and `check:docs` exit 1 before the spec / lint / client-react
packages were built; after the builds all exit 0. No changeset (docs
only).
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent c2ec298 commit fed0db8
2 files changed
Lines changed: 23 additions & 17 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
370 | 370 | | |
371 | 371 | | |
372 | 372 | | |
373 | | - | |
374 | | - | |
375 | | - | |
376 | | - | |
377 | | - | |
378 | | - | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
379 | 387 | | |
380 | 388 | | |
381 | 389 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
968 | 968 | | |
969 | 969 | | |
970 | 970 | | |
971 | | - | |
972 | | - | |
973 | | - | |
974 | | - | |
975 | | - | |
976 | | - | |
977 | | - | |
978 | | - | |
979 | | - | |
980 | | - | |
981 | | - | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
982 | 980 | | |
983 | 981 | | |
984 | 982 | | |
| |||
0 commit comments