Repository navigation
SqlDriver.applyFilterCondition 丢弃编译成空的 $and/$or 子过滤器,而不是套用布尔单位元 —— 与同仓 matchesFilterCondition / driver-memory 相反 #5134
Description
Activity
范围并入注记(PM 循环第 1 轮,会话
session_01Pbu27iNUfQCHeuS551Rqo7):#5146 分叉二与本单同函数同家族 ——$not: {}(及任何编译成空的$not子分组)在 Knex 下整条子句被丢弃,实测退化为 TRUE/全表,而 driver-memory / formula 给 FALSE/零行;按布尔代数与 cloud#1073 的单位元纪律,NOT TRUE ≡ FALSE,driver-sql 应在$not子分组编译为空时发方言 FALSE 常量。派发本单时把该情形并入验收(空$and→TRUE 单位元、空$or→FALSE 单位元、空$not→FALSE,三者同一批 pin 测试)。#5146 剩余的 NULL 语义分叉另行等维护者拍板,不在本单范围。
Generated by Claude Code
认领:PM 循环第 2 轮
会话:session_01Pbu27iNUfQCHeuS551Rqo7
分支:claude/issue-5134-sql-driver-boolean-identity
Worktree:objectstack-issue-5134
域:domain:engine
文件面:packages/plugins/driver-sql/src/sql-driver.ts(applyFilterCondition)及本包测试、changeset(越界即停,报告说明)范围含 07:29Z 注记并入的 #5146 分叉二(
$not空子分组 → 方言 FALSE)。⛔packages/spec/**零改动 ——FILTER_LOGIC_CASES定义在packages/spec/src/data/filter-logic-conformance.ts,一致性表扩条(建议 3)归 spec 车道,由 dev 立后续单移交;⛔ 不碰 driver-memory / formula(它们是对的参照)与 driver-mongodb(其对齐随一致性表后续单走)。在飞不相交已核:driver-sql 无其它单在飞。
Generated by Claude Code
验收:ACCEPT —— PR #5243(转 ready + 入队)
会话:
session_01Pbu27iNUfQCHeuS551Rqo7(PM 循环第 3 轮)落地内容:
applyFilterCondition改为结构性三值归约(reduceFilterNode→ true/false/clause)后再产 SQL —— 这是比派发词更好的形状:原缺陷正是「编译完再观察分组是否为空」的观察式判定,结构判定天然分得清「本来就空」与「有东西没编译出来」。空$and=TRUE(刻意的无子句)、空$or与空$not子组=方言 FALSE1=0(与read-scope-sql.ts同拼写)、{}析取项使整个$or为 TRUE;形状拒收(ADR-0112INVALID_FILTER,点名位置)含原型判定(Date/RegExp/class 实例枚举为空,不拦会被单位元升格为全表)。#5146 分叉二扩围落实;非空组合子逐字节不变;{field:{}}不越权裁决(→ #5240)。实况核验:draft ✓ / Fixes 行 ✓ / 3 文件在面内、spec 零改动 ✓ / 修前红证据(
$or:[null]实测全表)+ 修后全绿 / 同日 churn 处置完整:并入含 #5212 的 main(merge commitbb4d4994d,git merge-base --is-ancestor实证),并后全量重验 729+232 绿 / changeset 响亮标注查询行为变更与 RLS 影响。顺带发现处置:#5239 已分诊转 spec 车道队列(mongodb 同 PR 约束在案);#5240 已挂
needs-user-decision(PM 推荐序:拒收 > FALSE)。
Generated by Claude Code
- added 7 commits that reference this issue
on Aug 6, 2026 - added a commit that references this issue
on Sep 29, 2026 - added a commit that references this issue
on Oct 7, 2026
修 cloud#1073(Turso
RemoteTransport.buildWhereSQL的同一个 bug)时,按要求只读核对了框架侧SqlDriver的行为,发现同样的问题。按纪律不在那个 PR 里修,单独记在这里,unassigned。现象
packages/plugins/driver-sql/src/sql-driver.ts的applyFilterCondition这样编译$and/$or:空数组 / 空子过滤器都会让分组回调什么都不加,而 knex 对「没加任何子句的分组」不产出 SQL。用本仓自己的 knex(3.3.0,
packages/plugins/driver-sql/node_modules/knex,sqlite3 dialect)复现同一控制流:为什么是 bug
丢弃子句 ≠ 套用单位元。布尔代数里空 AND 是 TRUE、空 OR 是 FALSE,方向相反,而这段代码对两者都「当没看见」:
{ $and: [] }{ $or: [] }{ $or: [{a:1}, {}] }{}是 TRUE 析取项 → 全部行(("a" = ?))$and: []对的理由不是代码理解了单位元,而是「丢掉」在 AND 侧恰好等价于 TRUE,同一段代码在 OR 侧就必然错。关键点:这与同仓另外两个后端相反
filter-logic-conformance的 changeset 说得很明白,FilterCondition有四个独立实现,「一条 case 只有在每个后端都必须一致时才进表」。这三种形状没有进FILTER_LOGIC_CASES,于是四个后端在它们上面各行其是——而它们其实已经分成了两派:packages/formula/src/matches-filter.ts:35—if (!Array.isArray(val) || val.length === 0 || !val.some(...)) return false;,且被matches-filter.test.ts:80钉住:expect(m(rec, { $or: [] })).toBe(false); // empty OR matches nothing{}走evalNode空循环 →true(TRUE 析取项),$and: []走.every([])→true。三条全对。packages/plugins/driver-memory/src/memory-matcher.ts:31-35—.every()/.some()over[],match(rec, {})直接return true。三条全对。driver-sql— 三条里错两条(见上表)。driver-mongodb(mongodb-filter.ts:77)把空数组原样透传给 MongoDB,而 MongoDB 对空$and/$or是报错($and/$or must be a nonempty array)——第三种行为。也就是说:同一个
{ $or: [] },RLScheck(formula)判为拒绝、memory driver 判为零行、SQL driver 返回全表、mongodb 抛错。$or: []最常见的来源正是「本该有条件、但循环没填进去」,SQL 侧静默当成全表是其中最坏的一种兜底——在 RLS read scope 下推上,它意味着本该看不到任何行的人看到了整表。Spec 侧:三种形状都是声明合法的
packages/spec/src/data/filter.zod.ts:裸
z.array(...),没有.nonempty()/.min(1);元素类型的非递归半边是z.record(z.string(), z.unknown()),{}满足。所以正确动作是按单位元编译对,不是拒收。建议
applyFilterCondition的$or分支:全部析取项为空 → 产出该方言的 FALSE(如 knexwhereRaw('1 = 0'));任一析取项可证为 TRUE → 整个$or不产出子句。$and维持「编译掉」,但作为有意的单位元并加测试钉住。{})才编译成空」与「因为有东西没编译出来才编译成空」分开。$or: [null]/$or: ['x']/$or: [[...]]/$or: [new Date()]目前也都静默无痕消失;若不先把它们拦掉就上单位元,它们会升级成「匹配所有行」——比现在更糟。cloud 那边的做法是按形状在编译前拒收非 filter 节点的元素,使「编译成空」只剩一个成因。FILTER_LOGIC_CASES三条($and: []、$or: []、$or: [{a},{}]),让四个后端一次对齐——这正是那张表存在的意义。但注意driver-mongodb会因 MongoDB 拒收空数组而无法直接通过,需要它在 translate 时先做同样的单位元归约。关联
cloud#1073(Turso remote transport 的同一 bug 与其修法)、#3774(
$or分支内多键被 OR 而非 AND)、filter-logic-conformance。Generated by Claude Code