Commit 0c8a22f
feat(spec): one canonical conformance table for the filter logical combinators (#3812)
* feat(spec): one canonical conformance table for the filter logical combinators
`FilterCondition` is evaluated by four independent implementations — the SQL
compiler in driver-sql, driver-memory's matcher, formula's record-at-a-time
evaluator (the RLS write-side `check`), and service-analytics' read-scope SQL
lowering — and nothing held them to a shared standard.
#3774 was the cost: the SQL compiler OR-ed the contents within a `$or` branch
instead of AND-ing them, widening every `$or` filter. The other three were
correct by luck rather than by enforcement. That fix left three near-identical
shape tables copied across packages and the fourth backend unlocked entirely,
which is the same drift setup one step later.
`@objectstack/spec/data` now exports FILTER_LOGIC_ROWS and FILTER_LOGIC_CASES,
and each backend has a thin test that runs the shared rows through its own
evaluator. Adding a case to the table adds it to all four at once.
read-scope-sql is now verified by executing its SQL against a real engine and
comparing rows, not just by asserting the emitted string; it passes unchanged.
The table is a public export, so third-party driver authors can check a new
backend against the same standard.
Scope is deliberately limited to the logical combinators — null handling,
dates, coercion and LIKE escaping legitimately differ between a SQL engine and
a JS matcher, and folding them in would make the table unpassable.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(driver-sql): tighten the nested-filter assertion to exact ids
`should handle complex nested filters` asserted `toBeGreaterThan(0)`, which any
non-empty result satisfies — it could not distinguish a correct compile from a
wrong one.
To be precise about what this does and does not buy: the shape it exercises,
`{$or:[{$and:[…]},{$and:[…]}]}`, was never miscompiled by #3774. Each `$or`
branch holds a single `$and` key, so there were no sibling keys to wrongly OR;
I confirmed this by reverting the fix and watching the tightened assertion still
pass. The assertion is worth tightening because it was too weak to have caught
the difference either way, not because it now catches that bug.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(service-analytics): run the read-scope conformance on WASM SQLite
The first revision imported `better-sqlite3` and killed the vitest worker on
CI — a process-level abort with no JS error to catch, so all 17 conformance
cases silently did not run while the suite reported 22/23 files passing.
Reproduced locally under Node 20 (CI's version): `better-sqlite3@13` declares
`engines: >=22`, and a native binding is only loadable by the exact Node ABI it
was built for. `driver-sql` can afford that dependency because it falls back to
WASM SQLite when the binding fails to load; a test has no such fallback.
Switched to `sql.js` — the same engine that fallback lands on. Pure WASM, no
ABI to match, no build step. Verified on both Node 20 and Node 25: 17/17
conformance cases and 286/286 for the package.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>1 parent 763931e commit 0c8a22f
11 files changed
Lines changed: 461 additions & 302 deletions
File tree
- .changeset
- packages
- formula/src
- plugins
- driver-memory/src
- driver-sql/src
- services/service-analytics
- src/__tests__
- spec
- src/data
| 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 | + | |
Lines changed: 19 additions & 66 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
10 | 10 | | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
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 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
78 | 31 | | |
Lines changed: 14 additions & 65 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
13 | 10 | | |
14 | 11 | | |
15 | 12 | | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
| 13 | + | |
39 | 14 | | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 15 | + | |
64 | 16 | | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
75 | 24 | | |
Lines changed: 8 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
323 | 323 | | |
324 | 324 | | |
325 | 325 | | |
326 | | - | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
327 | 334 | | |
328 | 335 | | |
329 | 336 | | |
| |||
0 commit comments