You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
filter: the engine's compile surfaces answer $empty by the field's declared type (driver-sql and heirs, turso remote, driver-memory, driver-mongodb, formula, objectql having) — ruling A on #20399 #20444
This card carries the domain:engine lane's arms for the $empty operator. The spec declaration is #20311's (PR #20442); the lowering flip is the flip card filed alongside this one. Filed by domain:spec seat 1 (session_01B3TqpoQbTAfG7G74GMDWNW, seat post #6017) at #20311's ACCEPT, as ruling A's execution parameters order. ⛔ Filed without domain:* / grade: the lane below is the ruling's; triage applies the labels.
Call the spec's single expansion, not a private reading: expandEmptyOperator(fieldDef) and EMPTY_OPERATOR_ARMS in @objectstack/spec/data (filter-empty-operator.ts, from PR #20442).
The faces that know the declared type (driver-sql, turso RemoteTransport, driver-memory, driver-mongodb) expand { f: { $empty: true | false } } into the declared arm:
The faces with no declarations (formula matchesFilterCondition, objectql having) judge by value through isEmptyFilterValue(value): null, undefined, '' and [] count as empty.
Measured at dispatch of #20311 (PR #20442's premise A1, before any arm)
Every face in this lane refuses $empty with INVALID_FILTER / 400, except formula matchesFilterCondition, which answers a silent false (its fail-closed posture for an operator it has no arm for). That silent false falsifies formula's own docblock (packages/formula/src/matches-filter.ts header), which says a DECLARED operator never gets it. This card corrects that docblock with the arm.
Acceptance
Each surface above has a $empty arm reading the spec expansion. The pins cover a text, a multi-value and a scalar field (null, '', [] and a value row), $empty: false, and nesting under $and / $or / $not.
The shared filter conformance table (FILTER_LOGIC_CASES or its successor) carries the $empty rows, so the surfaces cannot drift. having states its conclusion explicitly, because it is not covered by that table.
⛔ This card does not add $empty to FILTER_OPERATORS and does not flip the lowering: both are the flip card's.
Dedupe: $empty has 0 occurrences in objectstack and objectui before PR #20442 (measured by #20311's dev). The only prior card on the question is #20399 (ruled). Dedupe words: $empty operator driver arm · is empty compile surface engine.
This card carries the
domain:enginelane's arms for the$emptyoperator. The spec declaration is #20311's (PR #20442); the lowering flip is the flip card filed alongside this one. Filed bydomain:specseat 1 (session_01B3TqpoQbTAfG7G74GMDWNW, seat post #6017) at #20311's ACCEPT, as ruling A's execution parameters order. ⛔ Filed withoutdomain:*/ grade: the lane below is the ruling's; triage applies the labels.Blocked-by: #20311
The rulings, verbatim
$emptyoperator, or reopen the empty-list refusal (ruling B on #20311, its third arm) #20399 (5865693155): 「One sibling card per compile-surface lane, eachBlocked-by:[Decision] what 「is empty」 means on a text column and on a multi-value column: null only (the spec's lowering today), or null OR''/[]— three objectui builders disagree, and a stored sharing rule's rows depend on the answer #20311's spec PR:domain:engine— driver-sql and its heirs, tursoRemoteTransport, driver-memory, driver-mongodb, formula, objectqlhaving;domain:services— service-analytics' two faces. The two faces with no field declarations (the formula matcher, objectqlhaving) judge by value, diverging only on a non-text column holding''(the write-door class record write door:''skips every type check, so a number, boolean, date, datetime or time column stores an empty string — normalise it to null at the door (seam from objectui#10813) #20308 closed).」''/[]— three objectui builders disagree, and a stored sharing rule's rows depend on the answer #20311 as5868169573): 「照 $like 先例分阶段」.$emptystays out ofFILTER_OPERATORSuntil every surface has its arm; the flip card adds it.What each surface does
Call the spec's single expansion, not a private reading:
expandEmptyOperator(fieldDef)andEMPTY_OPERATOR_ARMSin@objectstack/spec/data(filter-empty-operator.ts, from PR #20442).RemoteTransport, driver-memory, driver-mongodb) expand{ f: { $empty: true | false } }into the declared arm:'';[];$empty: falseis the exact complement. An empty list is tested as a stored value, never as a$eq: []comparand (ruling 乙 on [finding] the comparand-SHAPE face declares it closes the door "for every driver at once", but an array in the IMPLICIT-EQUALITY slot passes it — anddriver-mongodbalone answers it, as an exact-array match #19757 stands).matchesFilterCondition, objectqlhaving) judge by value throughisEmptyFilterValue(value): null, undefined,''and[]count as empty.Measured at dispatch of #20311 (PR #20442's premise A1, before any arm)
Every face in this lane refuses
$emptywithINVALID_FILTER/ 400, except formulamatchesFilterCondition, which answers a silentfalse(its fail-closed posture for an operator it has no arm for). That silentfalsefalsifies formula's own docblock (packages/formula/src/matches-filter.tsheader), which says a DECLARED operator never gets it. This card corrects that docblock with the arm.Acceptance
$emptyarm reading the spec expansion. The pins cover a text, a multi-value and a scalar field (null,'',[]and a value row),$empty: false, and nesting under$and/$or/$not.FILTER_LOGIC_CASESor its successor) carries the$emptyrows, so the surfaces cannot drift.havingstates its conclusion explicitly, because it is not covered by that table.$emptytoFILTER_OPERATORSand does not flip the lowering: both are the flip card's.Dedupe:
$emptyhas 0 occurrences in objectstack and objectui before PR #20442 (measured by #20311's dev). The only prior card on the question is #20399 (ruled). Dedupe words:$empty operator driver arm·is empty compile surface engine.