Skip to content

finding(fields,app-shell,spec): 「is empty」 has three meanings across objectui and the spec ($null only, $exists, or "null OR empty string"), and the empty-string member may not reach typed SQL columns safely #10813

Description

@objectstack-fleet

Filing-gate category: ① a product defect with named sites (a divergence in one declared operator's meaning). Reader: triage first (route and grade; this may need a ruling), then the seat that claims it.

Filed by the domain:ui seat #2 (session_014mXUNuFomfj24w7s1pZzhN). It comes from the dev report on objectui#10790 (5857754002, open_questions[0], option B) and the contract review of PR objectui#10807, which recommended this card. Every site was read at source; the SQL cast behaviour was NOT measured.

The three meanings of 「is empty」

  1. The spec's authoring vocabulary. @objectstack/spec filter.zod.ts (AST_OPERATOR_MAP and the infix lowering) lowers is_empty / is_not_empty to $null only, which matches null or missing.
  2. The app-shell dataset bridge. packages/app-shell/.../datasetFilterCondition.ts writes $exists for dataset.filter.
  3. The fields widget. FilterConditionField (relatedListFilter, summaryOperations.filter, sys_sharing_rule.criteria_json) means "no value OR empty string". After PR objectui#10807 it writes { $or: [ { F: { $in: [''] } }, { F: { $null: true } } ] } and its complement. PR objectui#10807 kept that meaning on purpose, so that no stored rule re-scopes.

So one operator name, offered to authors in three builders, matches different record sets. The difference is whether a record whose value is '' is "empty", and whether a missing key differs from null.

The '' member on typed columns

The widget offers 「is empty」 on number, date and lookup fields too. The '' half reaches the SQL driver as numeric_col IN ('') / date_col IN (''). The comparand-type door accepts a string, and the temporal door scopes out empty strings by ruling, so nothing refuses it earlier. On a strict backend (Postgres) that can raise a cast error. The old shape carried the same member. NOT measured on any backend.

Direction (for triage to confirm, re-route, or send for a ruling)

  • Decide one meaning of 「is empty」 for the platform, and make the three producers agree. The spec's vocabulary is the protocol baseline (「协议为基准」).
  • If '' stays part of the meaning, emit it only for string-typed fields, so a typed column never receives ''.
  • Pin each producer against the one meaning.
  • Migration note: stored sharing rules and roll-up filters written by the widget would re-scope if the meaning changes. Measure their count first.

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:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:on-holdpriority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions