由 #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 侧的做法,可直接照搬的两点:
- 结构性归约,不要观察式判空。 「编译完再问后端有没有产出条件」分不清「因为本来就是空」和「因为有东西没编译出来」;先把整棵 filter 树归约成
true / false / clause 三值,再据此产出。
- 先做形状拒收,再上单位元。
$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 语义,待维护者拍板)。
由 #5134 的实现单移交给 spec 车道(#5134 的文件面明令
packages/spec/**零改动,故一致性表扩条不在那一单内)。要做什么
在
packages/spec/src/data/filter-logic-conformance.ts的FILTER_LOGIC_CASES里补四条:{ $and: [] }{ $or: [] }{ $or: [{ a: 'x' }, {}] }{}是 TRUE 析取项{ $not: {} }NOT TRUE ≡ FALSE这张表一加,四个后端(
driver-sql、driver-memory、formula的matchesFilterCondition、read-scope-sql)就同时被钉住 —— 这正是 #3774 建这张表的理由。为什么必须和 driver-mongodb 一起落地(否则一定红)
现状实测:
formula/driver-memory—— 四条本来就全对,加进表里直接绿。driver-sql—— 四条由 SqlDriver.applyFilterCondition 丢弃编译成空的 $and/$or 子过滤器,而不是套用布尔单位元 —— 与同仓 matchesFilterCondition / driver-memory 相反 #5134 修好(本 issue 的上游),届时绿。driver-mongodb(packages/plugins/driver-mongodb/src/mongodb-filter.ts)—— 把空数组原样透传给 MongoDB,而 MongoDB 对空$and/$or直接报错($and/$or must be a nonempty array)。所以它今天既不是 TRUE 也不是 FALSE,是第三种行为:抛异常。因此扩表的 PR 必须同时给
mongodb-filter.ts的 translate 层加同一套单位元归约(空$and→ 不产出条件;空$or→ 产出一个匹配零行的条件,如{ _id: { $in: [] } }或等价的$expr: false;$not: {}同理归约为零行),否则一致性表一加就把 mongodb 的 cell 打红。两者同 PR,或明确排序后连续两 PR。参考实现与设计约束
#5134 在 driver-sql 侧的做法,可直接照搬的两点:
true/false/clause三值,再据此产出。$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 语义,待维护者拍板)。