Skip to content

[spec] FILTER_LOGIC_CASES 补空组合子的布尔单位元四条 —— 需与 driver-mongodb 的单位元归约同时落地 #5239

Description

@os-zhuang

#5134 的实现单移交给 spec 车道(#5134 的文件面明令 packages/spec/** 零改动,故一致性表扩条不在那一单内)。

要做什么

packages/spec/src/data/filter-logic-conformance.tsFILTER_LOGIC_CASES 里补四条:

filter 期望 依据
{ $and: [] } 全部行 空合取 = TRUE(AND 单位元)
{ $or: [] } 零行 空析取 = FALSE(OR 单位元)
{ $or: [{ a: 'x' }, {}] } 全部行 {} 是 TRUE 析取项
{ $not: {} } 零行 NOT TRUE ≡ FALSE

这张表一加,四个后端(driver-sqldriver-memoryformulamatchesFilterConditionread-scope-sql)就同时被钉住 —— 这正是 #3774 建这张表的理由。

为什么必须和 driver-mongodb 一起落地(否则一定红)

现状实测:

因此扩表的 PR 必须同时给 mongodb-filter.ts 的 translate 层加同一套单位元归约(空 $and → 不产出条件;空 $or → 产出一个匹配零行的条件,如 { _id: { $in: [] } } 或等价的 $expr: false;$not: {} 同理归约为零行),否则一致性表一加就把 mongodb 的 cell 打红。两者同 PR,或明确排序后连续两 PR。

参考实现与设计约束

#5134 在 driver-sql 侧的做法,可直接照搬的两点:

  1. 结构性归约,不要观察式判空。 「编译完再问后端有没有产出条件」分不清「因为本来就是空」和「因为有东西没编译出来」;先把整棵 filter 树归约成 true / false / clause 三值,再据此产出。
  2. 先做形状拒收,再上单位元。 $or: [null] / $or: ['x'] / $or: [[…]] / $or: [new Date()] 这类非 filter 节点若不先拦掉,单位元会把它们从「被静默忽略」升级成「匹配所有行」,比原 bug 更坏。注意 Date / RegExp / class 实例都满足 typeof x === 'object' 却枚举为空 —— 必须用原型判定,不能只判 typeof

关联:#5134(driver-sql 侧,已实现)、cloud#1073(Turso RemoteTransport.buildWhereSQL 同一 bug 与同一修法)、#3774(一致性表的由来)、#5146($not 的另一分叉:NULL 语义,待维护者拍板)。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions