Commit 9ecdca9
`ObjectQLStrategy.buildFilterClauseSql` is the third compiler of the analytics
filter tree — the one whose output is echoed to the browser. It handled
`set`/`notSet`/`in`/`notIn`/`contains`/`notContains` explicitly and sent
everything else to `SCALAR_SQL_OPS`, whose six entries do not include
`startsWith`/`endsWith`; the unmapped exit was `return null`, which every
compiler of this tree reads as "this node carries no constraint".
So `{stage: {$startsWith: 'w'}}` echoed a statement with no WHERE at all while
the query it documents ran `stage LIKE 'w%'`. The echo was strictly WIDER than
execution, and its only reason to exist is reproducing execution: an author
debugging "why does this chart show fewer rows" ran it, got more rows, and
concluded the filter never applied. Same class as #3601 / #3602 / #3650,
reached through the operator table.
Two changes:
1. `LIKE_SQL_OPS` collects the four LIKE-family operators with their SQL
spelling and pattern, one row each, mirroring `NativeSQLStrategy`'s
`opMap`/`likePattern` pair so the two tables sit side by side and drift is
visible. `contains`/`notContains` output is byte-identical.
2. The unmapped exit THROWS instead of returning null. It can, because the
upstream vocabulary is closed: `fieldLeaves` in `filter-normalizer.ts` is
the only leaf producer and refuses an operator outside `MONGO_TO_CUBE_OP`
with INVALID_FILTER/400 before a leaf exists. An arrival therefore means
our own two tables drifted — same call `convertFilter`'s `default:` arm
made in #4128 — and a silently wider query is the one answer that must not
be given. Deliberately not the 400 envelope: this is not a caller mistake.
Measured: this exit is unreachable through the public door today, so
reverting it to `return null` turns exactly one assertion red and leaves
the enumeration green. It is a drift tripwire, not the behaviour fix.
`objectql-echo-operator-coverage.test.ts` pins the issue's table by ROW IDS —
the echoed statement is executed against the same fixture and its rows compared
to what the query returns — then enumerates all 15 of `filter.zod.ts`'s
`FILTER_OPERATORS`, asserting each renders a predicate with placeholders and
`params` aligned.
Claude-Session: https://claude.ai/code/session_01BWS4heBoAitLmzCLhcYdbK
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 229d29e commit 9ecdca9
3 files changed
Lines changed: 511 additions & 6 deletions
File tree
- .changeset
- packages/services/service-analytics/src
- __tests__
- strategies
| 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 | + | |
| 54 | + | |
0 commit comments