Skip to content

driver-memory analytics 面:同一字段上的多个算子互相覆盖,{qty: {$gte:150, $lte:250}} 只剩最后一个 —— 区间塌成单边,结果被放大 #5440

Description

@os-zhuang

做 #5374($notContains 编译成裸 {$not: 'x'})时,为了确认修复没有把 $match 的组装弄坏,逐个实测了「一个 where 里同一字段带多个算子」会编译成什么。这一条不属于 #5374 的范围面 —— #5374 裁的是算子 → 谓词这一层(映射指向了错的目标),这一条在谓词 → $match 的组装这一层,#5374 修好之后依然完整存在。按 Prime Directive #10 单独记在这里,unassigned。

位置

packages/plugins/driver-memory/src/memory-analytics.ts,query() Stage 1 的 $match 组装循环(约 :180):

for (const filter of normalizedFilters) {
  const fieldPath = this.resolveFieldPath(cube, filter.member);
  matchStage[fieldPath] = /* 该条目的谓词 */;   // ← 直接赋值,不合并
}

flattenFilterCondition 对 {field: {$op1: a, $op2: b}} 会 push 两条 NormalizedCubeFilter,member 都是 field。两条都以 matchStage[fieldPath] = … 落盘,于是后一条覆盖前一条,前一个算子彻底消失。

现象(实测)

3 行数据,qty 分别为 100 / 200 / 300(id 分别为 1/2/3)。左列是 find(),右列是 analytics 面 —— 两列都是在 #5374 修复之后测的,即这条与那条无关:

where find() analytics 实际编译出的 $match
{qty: {$gte: 150, $lte: 250}} [2] [1,2] {qty: {$lt: 250}}
{qty: {$ne: 300, $gt: 150}} [2] [2,3] {qty: {$gt: 150}}

方向是放大:丢掉的永远是一个约束,所以行只会变多,不会变少。这与 #5345 / #5373 / #5374 是同一个方向、同一类后果 —— 一个看起来正常的图表统计了它本该排除的行 —— 只是机制换成了「谓词被生成了,但被下一个谓词覆盖掉」。

为什么是 bug

  1. {$gte, $lte} 是区间的规范写法。 AnalyticsQuery.where 是 FilterCondition,而 dashboard widget 元数据直接用这个形状表达「金额在某区间」「日期在某窗口」。这恰恰是最常见的多算子写法,不是边角。
  2. declared ≠ enforced。 ANALYTICS_FILTER_CAPABILITIES 声明本面支持这 11 个算子,assertFilterConditionShape 也放行了 {$gte, $lte} 这个形状 —— 声明能算,实际只算了一半。
  3. 另一半是对的。 live query path 的 normalizeFieldOperators 把同字段的多个算子合并进一个对象,多个 regex 型算子还会通过 _multiRegex 提升成 $and。所以这是同一个 driver 的两面对同一个 where 给出不同行集 —— { field: {} }(零个操作符的字段约束)在同仓有三个答案:driver-sql 组合子内 TRUE、顶层抛 INVALID_FILTER、formula/driver-memory FALSE #5240 为本包立下的不变量所禁止的形状。

建议(不代裁决)

不是一行改。合并本身容易(matchStage[fieldPath] = {...existing, ...predicate}),但有两处必须一起想清楚,否则会把一个覆盖换成另一个覆盖:

另一条路是拒收同字段多算子(与 #5345 同款),但那会拒掉本面 find() 明明能算、且是 widget 常用形状的查询,恐怕不是想要的答案。

未验证的部分

关联:#5374(同文件、同一轮核对里发现;它裁的是算子→谓词层,本条是谓词→$match 组装层)、#5345、#5373、#5240(本包两面不得分叉)、#3948(no-silent-drop)。

Activity

  1. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    分诊(backlog sweep,主 backlog 代扫):挂 pm:queue + domain:engine。理由:落点 packages/plugins/driver-memory/src/memory-analytics.ts(同字段多算子互相覆盖,区间塌成单边);实测证据具体,符合 auto-queue 判据。⚠️ 同文件族串行:#5433 / #5440 / #5442 / #5444 落同一文件,认领时严格跨轮串行。不构成认领。会话:session_01N3uGFF8teXbpgtbEJ1aYXu


    Generated by Claude Code

  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    转 pm:on-hold(2026-08-05,维护者裁决,锚点 #5499):driver-memory 为早期测试便利组件,方向已定 sqlite 内存模式替代,缺陷修复投入冻结(撤销今晨 12:2xZ 的入队分诊——当时冻结裁决尚未下达)。重启条件:替代在测试面完成后随锚点整批关闭;若影响 CI 判绿正确性,按 restore-invariant 例外升级。不派发、不催。会话:session_01N3uGFF8teXbpgtbEJ1aYXu


    Generated by Claude Code

  3. added a commit that references this issue on Aug 6, 2026
    01c0bae
  4. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    按 #5499 重启条件 + #5704 收口关闭(not planned):维护者 2026-08-06 裁定 driver-memory 的测试职能由 sqlite :memory: 替代,迁移已完成(PR #5715 / #5797 / #5806);本包处于投入冻结(#5499),analytics 面缺陷不再计划修复。若维护者后续裁定包本体保留并解冻,可重开。


    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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions