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

  1. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    分诊(engine/services 车道 PM,会话 session_01Pbu27iNUfQCHeuS551Rqo7):落点 packages/spec(FILTER_LOGIC_CASES)+ driver-mongodb translate 层,共享契约面归 spec 车道 —— 打 domain:spec + pm:queue 经队列标签移交,labeling ≠ claiming,本会话不认领。上游 #5134 的 driver-sql 侧已交付(PR #5243,验收中);「与 mongodb 单位元归约同 PR 落地否则表一加即红」的约束请原样进派发词。注意 #5240({field:{}} 三答案)拍板后该 case 也应进同一张表 —— 两单排序由 spec 车道自定。


    Generated by Claude Code

  2. self-assigned this
    on Aug 4, 2026
  3. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    认领:PM 循环第 4 批(spec 车道,batch:5;维护者 B 级合批指令 —— 本单锚定,同批携带 #5146 与 #5240 的 spec 半边)
    会话:session_01ErbEDVAg1No9gdg1pgDAGB
    分支:claude/issue-5239-filter-logic-identity-batch
    Worktree:objectstack-issue-5239
    域:domain:spec(跨域合批,维护者已授权)
    文件面(跨域声明,全量):packages/spec/src/data/filter-logic-conformance.ts(FILTER_LOGIC_CASES 扩条)、packages/spec/src/data/filter.zod.ts(仅 FilterConditionSchema 的 $not NULL 语义契约 TSDoc,#5146 spec 半边;⛔ 不动 #5306 刚落的 FilterArray 声明)、packages/plugins/driver-mongodb/src/mongodb-filter.ts(单位元归约,与表扩条同 PR 的硬约束)及其测试、spec 生成基线(os-regen 四步)、.changeset/*.md

    合批构成:(1) #5239 四条布尔单位元 + mongodb 归约同落;(2) #5146 spec 半边(NULL-safe 已随 #5296 进 main,表行应即绿);(3) #5240 spec 半边受限携带 —— 拒收 case 仅当可表达为期望拒收且对当前 main 全绿才进表(其 engine 半边四后端闸门未实现,提前进表即打红四格),否则只留契约注记引 #5240,实测定夺并回报。


    Generated by Claude Code

  4. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    交付进展(会话 session_01ErbEDVAg1No9gdg1pgDAGB):PR #5323(draft)。

    硬约束半边已交付:mongodb-filter.ts 的结构性单位元归约 + 形状拒收(先拒收后归约),含 45 条 pin。顺带堵掉三条改前就已经在放宽的:{$or:[new Date()]} → {$or:[{}]}、{$or:'x'} / {$not:null} → {},全都是「每一份文档」,而 updateMany / deleteMany 走同一个 translate 层。

    四条表行没有加进去 —— 本单前提部分不成立。 正文点名的四个后端里 read-scope-sql 就红四格,同包的 filter-normalizer(native-sql-filter-logic-conformance.test.ts 在册跑全表)也红四格。实测(origin/main @ 175d789):两者对空 $and/$or fail-closed 抛错、{$not:{}} 给整表、{$or:[{a},{}]} 给行 1,2。而且这不是「没跟上」—— filter-normalizer.ts 的错误消息逐字反对「treating it as match nothing」,read-scope-sql.test.ts:86 还把抛错钉住了,是两条已落地立场对立。属公开契约定调,已立 #5322 上交拍板(含两轴分析与推荐),本单待其拍板后补表行。

    同批的另两族也实测后未进表,理由同样记在 PR 与 filter-logic-conformance.ts 的实测矩阵里:#5146 spec 半边的契约 TSDoc 已写进 FilterConditionSchema(NULL-safe $not),但跨驱动 case 行受同两个后端阻塞(#5297,已在该单补注 filter-normalizer.ts 是同缺陷第二份拷贝);#5240 除闸门未实现外,FilterLogicCase 本身无法表达「期望拒收」(expected 是行 id 列表,空列表 = 匹配零行,恰是裁定没取的 FALSE),要进表得先扩表结构,按纪律不擅自发明。


    Generated by Claude Code

  5. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    PM 记录(session_01ErbEDVAg1No9gdg1pgDAGB):PR #5323 已验收,交付本单的 driver-mongodb 硬约束半边(空组合子结构性归约 + 非节点形状拒收)与 #5146 的 spec TSDoc 半边。

    四条一致性表行没有进表 —— 前提复核推翻了「只差 mongodb 一家」:在册后端 read-scope-sql 与 analytics filter-normalizer 对同四条持成文的相反立场(fail-closed 抛错,有 pin 钉住),已立 #5322 上交拍板。

    追踪拓扑(PM 裁定,如有异议可 reopen):本单随 PR #5323 合并关闭;四条表行的唯一在册追踪是 #5322 —— 裁决落地的 PR 一并加行,filter-logic-conformance.ts 里已留全部实测矩阵与操作指引,不再双开追踪。#5240 的表结构缺口(FilterLogicCase 无法表达「期望拒收」)也已记录在同处,归引擎车道四后端闸门时一并定形。


    Generated by Claude Code

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