Skip to content

Commit 80b111c

Browse files
committed
fix(spec): both null ordering-comparand refusals say the evaluation faces do not agree
Measured, driver-sql and formula agree on an ordering against null (both admit no row), so "no two evaluation faces agree" was false read pairwise. The schema-door message (nullOrderingComparandMessage) and its runtime twin (nullOrderingComparandError) now both say "the evaluation faces do not agree"; every other sentence of each is unchanged. The vocabulary assertion's every-face list now also names driver-sql and driver-turso's remote transport, which clearing $empty edited. Claude-Session: https://claude.ai/code/session_01YDt3PzwfrkuFzUBF89WPmM Co-authored-by: Claude <noreply@anthropic.com>
1 parent c28172b commit 80b111c

4 files changed

Lines changed: 15 additions & 9 deletions

File tree

‎.changeset/21397-null-ordering-message-faces.md‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
'@objectstack/spec': patch
33
---
44

5-
fix(spec): the null ordering-comparand refusal names only evaluation faces that exist
5+
fix(spec): the null ordering-comparand refusals name only evaluation faces that exist, and say only what was measured
66

77
Clause-②: no
88

@@ -14,7 +14,12 @@ and were measured to disagree: driver-memory's query path reads a stored `null`
1414
comparand, so `{"$gte": null}` admits that row, while driver-sql compares against SQL `NULL` and
1515
admits no row.
1616

17-
Text only: the first sentence (`null is not a valid $gt comparand.` and its siblings), the prescription
18-
(`{"$eq": null}` / `{"$ne": null}`) and the ruling sentence are unchanged, and the schemas accept
19-
and refuse exactly the same filters. A client or log filter that matches the old parenthesis needs
20-
the new spelling.
17+
That refusal and its runtime twin, the `parseFilterAST` refusal for the same comparand
18+
(`Operator "$gt" on field "…" does not accept a null comparand …`), both said "no two evaluation
19+
faces agree" on what an ordering against `null` matches. Measured, two faces do agree (driver-sql
20+
and formula both admit no row), so both now say "the evaluation faces do not agree".
21+
22+
Text only: each message's first sentence, its prescription (`{"$eq": null}` / `{"$ne": null}`), the
23+
schema door's ruling sentence and the runtime door's "NOT applied" sentence are unchanged, and both
24+
doors accept and refuse exactly the same filters. A client or log filter that matches the old
25+
wording needs the new spelling.

‎packages/spec/src/data/filter-comparand-shape.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ function nullOrderingComparandError(
703703
return invalidFilterComparandError(
704704
context,
705705
`Operator "${op}" on field "${field}" does not accept a null comparand (at ${path}). ` +
706-
`null is not ordered; no two evaluation faces agree on what it matches. State absence ` +
706+
`null is not ordered; the evaluation faces do not agree on what it matches. State absence ` +
707707
`with the null predicate: {"$eq": null} is "has no value", {"$ne": null} is "has a value". ` +
708708
`Authoring spellings: ${spellings.join(', ')}. The filter was NOT applied, and an ` +
709709
`unapplied filter would have returned the UNFILTERED result set.`,

‎packages/spec/src/data/filter-operator-vocabulary.test.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ describe('the declaration surface and the enforcement surface', () => {
8383
+ 'so declaring ahead of the arms is the correct staging. To stage one: declare it in '
8484
+ 'FieldOperatorsSchema, add it to the array THIS assertion compares against, and note on '
8585
+ 'FILTER_OPERATORS which issue implements it. To clear one: implement it on EVERY face '
86-
+ 'in ONE PR — spec word list, driver-memory (query path, analytics face), '
87-
+ 'driver-mongodb, service-analytics (3 compilers), objectql `having`, formula — '
86+
+ 'in ONE PR — spec word list, driver-memory (query path, analytics face), driver-sql, '
87+
+ 'driver-turso (remote transport), driver-mongodb, service-analytics (3 compilers), '
88+
+ 'objectql `having`, formula — '
8889
+ 'then empty this list. #6520 is the worked example of the clearing direction.',
8990
).toEqual(STAGED_AHEAD_OF_BACKENDS);
9091
});

‎packages/spec/src/data/filter.zod.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ const ORDERING_COMPARAND_DESCRIPTION =
465465
*/
466466
function nullOrderingComparandMessage(op: string): string {
467467
return (
468-
`null is not a valid ${op} comparand. null is not ordered, and no two evaluation faces `
468+
`null is not a valid ${op} comparand. null is not ordered, and the evaluation faces do not `
469469
+ 'agree on what an ordering against it matches (driver-memory\'s query path reads a '
470470
+ 'stored null as equal to it, so {"$gte": null} admits that row; driver-sql compares '
471471
+ 'against SQL NULL and admits no row). State absence '

0 commit comments

Comments
 (0)