Skip to content

objectql: a string comparand against a boolean field answers wrong rows under 200 — "true"/"false" match nothing, $ne "true" returns the true row, and ?f=true / ?f=false on the GET door both answer zero rows #21333

Description

@objectstack-fleet

QA-source: #21330 · api-backend.filter-comparand-conformance · outside the item's clauses (found while driving it)

What fails

A boolean field compared with a string comparand is neither refused nor narrowed: the engine compares text against the stored 1/0 and answers 200 with the wrong rows. The number door (#20351) and the temporal door judge their declared types; there is no boolean twin, and the 17.6.0 notes ("A filter is refused where it used to answer the wrong rows") list no boolean case — the number door's own contract says a boolean against a boolean field "is not this door's subject".

Reproduction (stock showcase on 17.6.0 617f25f8, admin; showcase_field_zoo has 2 rows, one f_boolean=true, one false)

All POST /api/v1/data/showcase_field_zoo/query:

where status rows correct answer
{"f_boolean":"true"} 200 0 1 (or a 400)
{"f_boolean":{"$eq":"true"}} 200 0 1 (or a 400)
{"f_boolean":{"$in":["true"]}} 200 0 1 (or a 400)
{"f_boolean":{"$ne":"true"}} 200 2 — includes the true row 1 (or a 400)
{"f_boolean":"false"} 200 0 1 (or a 400)
{"f_boolean":"yes"} 200 0 a 400
controls true, 1, "1" 200 1 —
control false 200 1 —

Other doors give the same wrong answers:

  • GET /api/v1/data/showcase_field_zoo?filter={"f_boolean":"true"}, ?$filter=…, ?filter=[["f_boolean","=","true"]] → 0 rows each.
  • Bare query parameters, where every value is a string: GET /api/v1/data/showcase_field_zoo?f_boolean=true → 0 rows, ?f_boolean=false → 0 rows; only ?f_boolean=1 / 0 work.
  • Aggregate: {"where":{"f_boolean":"true"},"aggregations":[{"function":"count","alias":"n"}]} → {n:0}.

Reproduced on two fresh boots by the runner and twice more by an independent verifier.

Expected

Either refuse a non-boolean comparand on a boolean field (400 INVALID_FILTER, as the number door does for numbers), or narrow "true"/"false" to booleans at a declared-type door — never a silent wrong answer. The $ne cell (returns the row it should exclude) and the bare ?f=true GET door are the most harmful.

Where

objectstack — a boolean twin of packages/objectql/src/number-comparand-declared-type-door.ts, with its contract beside packages/spec/src/data/filter-number-comparand-declared-type.ts. Severity (verifier): major — wrong data, no error. Not a 17.6.0 regression.

Full run evidence: #21330.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:specpriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions