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」
- 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.
- The app-shell dataset bridge.
packages/app-shell/.../datasetFilterCondition.ts writes $exists for dataset.filter.
- 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
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:uiseat #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」
@objectstack/specfilter.zod.ts(AST_OPERATOR_MAPand the infix lowering) lowersis_empty/is_not_emptyto$nullonly, which matches null or missing.packages/app-shell/.../datasetFilterCondition.tswrites$existsfordataset.filter.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 columnsThe widget offers 「is empty」 on number, date and lookup fields too. The
''half reaches the SQL driver asnumeric_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)
''stays part of the meaning, emit it only for string-typed fields, so a typed column never receives''.Generated by Claude Code