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.ts 的 FILTER_LOGIC_CASES 里补四条:

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

这张表一加,四个后端(driver-sql、driver-memory、formula 的 matchesFilterCondition、read-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 语义,待维护者拍板)。

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions