Commit 9bf4dd0
`MemoryAnalyticsService` has two exits for one normalized filter tree and they
disagreed about what the LIKE family MEANS. `query()` builds a real containment
pattern; `generateSql()` emitted the comparand as a bare literal with no
wildcard anywhere, so `{name: {$contains: 'acme'}}` echoed
`WHERE name LIKE 'acme'` — an EQUALITY — beside a chart drawn from every row
CONTAINING `acme`. `notContains` mirrored it through `NOT LIKE`.
The `$contains` family now renders `GLOB '*v*'` / `NOT GLOB`, and `$icontains`
`lower(col) GLOB lower('*v*')`. GLOB rather than LIKE because this exit emits
SQLite-shaped SQL and SQLite's LIKE folds ASCII unconditionally, while #4706
Q2 = A rules the family case-SENSITIVE and #7723 put this package's execution
faces on that answer — a LIKE echo would have contradicted execution on a
second axis the moment the wildcards were added. The translation is the spec's
shared `likePatternToGlobPattern`, over a LIKE-escaped comparand, so an
author's own `%` / `_` / `*` / `?` / `[` stay literal instead of becoming the
match-every-row bypass (#5567).
`operatorToSql`'s `|| '='` fallback is gone with it: a name→name map cannot
hold a wildcard, a list, or a null-safe negation, so it is now a builder table
keyed by `CubeOperator` — the shape #5374 gave the mingo exit — and a widened
vocabulary fails to compile until its SQL spelling exists. Three operators were
reaching that fallback and are fixed with it: `{$in: [a,b]}` echoed `= a`,
`{$nin: [a]}` echoed the exact COMPLEMENT of the query's rows, and
`{$exists: true}` echoed `name = 1`, which selects nothing. Three smaller
divergences on the same builder went too — negations are null-safe (#5146 /
#5297), an empty `$in`/`$nin` renders a predicate instead of no WHERE, and a
bare-day `$lte` renders half-open as the pipeline has read it since #4042.
`startsWith` / `endsWith` never reached the fallback and are unchanged: this
face does not lower them, so both exits refuse them with `INVALID_FILTER` / 400.
`memory-analytics-echo-operator-coverage.test.ts` pins the WHERE against
`query()`'s ROW SET by executing the echoed statement on a real SQLite engine
(`sql.js`), enumerates the closed vocabulary on both exits, and records the
eight-way reverse verification. Only the DISPLAYED SQL changes; `query()`'s
rows are untouched.
Claude-Session: https://claude.ai/code/session_01TPYmYr8mjAsbZ6RqwEk4TT
Co-authored-by: Claude <noreply@anthropic.com>
1 parent c9c2d92 commit 9bf4dd0
7 files changed
Lines changed: 813 additions & 71 deletions
File tree
- .changeset
- packages/drivers/driver-memory
- src
| 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 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
28 | 30 | | |
29 | 31 | | |
30 | 32 | | |
| |||
0 commit comments