@inixiative/json-rules 2.18.4 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -494,6 +494,31 @@ Not every backend supports every rule shape.
494
494
  | Windowing (`orderBy` / `take` / `skip`) | Yes | Extremal (`take:1`, aligned) | No |
495
495
  | `path: '$.field'` current-element / same-row refs | Yes | No | Yes |
496
496
 
497
+ ### NULL Semantics
498
+
499
+ A negated operator is the complement of its positive form — the same answer
500
+ `check()` gives, where `null !== 'x'` is simply true. SQL's three-valued logic
501
+ disagrees (`col <> 'x'` is NULL, never true, for a NULL column), so the
502
+ compilers carry NULL rows explicitly:
503
+
504
+ | Rule | `check()` on `{ col: null }` | `toSql()` | `toPrisma()` (nullable column) |
505
+ | --- | --- | --- | --- |
506
+ | `notEquals 'x'` / `notContains` / `notMatches` / `notBetween` | matches | `(col <> $1 OR col IS NULL)` | `{ OR: [{ col: { not: 'x' } }, { col: { equals: null } }] }` |
507
+ | `notIn ['x']` | matches | `(col <> ALL($1) OR col IS NULL)` | `{ OR: [{ col: { notIn: ['x'] } }, { col: { equals: null } }] }` |
508
+ | `in ['x', null]` | matches | `(col = ANY($1) OR col IS NULL)` | `{ OR: [{ col: { in: ['x'] } }, { col: { equals: null } }] }` |
509
+ | `notIn ['x', null]` | no match | `(col <> ALL($1) AND col IS NOT NULL)` | `{ AND: [{ col: { notIn: ['x'] } }, { col: { not: null } }] }` |
510
+ | `equals` / `notEquals` with `path: '$.other'` | `null === null` | `IS [NOT] DISTINCT FROM` | — |
511
+ | `exists` / `notExists` | `!= null` / `== null` | `IS NOT NULL` / `IS NULL` | `{ not: null }` / `{ equals: null }` |
512
+
513
+ `toPrisma()` can only add the null arm when it knows the column is nullable —
514
+ an `equals: null` on a NOT NULL column is a Prisma validation error. Nullability
515
+ comes from the field map: `FieldMapEntry.isRequired: false` (prisma-map emits it).
516
+ Without `{ map, model }`, or on an entry that doesn't declare it, the bare
517
+ `not` / `notIn` is emitted and NULL rows fall out, as they always did.
518
+
519
+ Date rules are unaffected: `check()` throws on a NULL date column rather than
520
+ answering, and the compilers keep the bare `NOT BETWEEN`.
521
+
497
522
  ### Prisma Limitations
498
523
 
499
524
  - `matches` and `notMatches` are not supported by Prisma output