Skip to content

driver-mongodb 带着 #5328 的同一条缝:形状错误的 $between / 非数组 $and$or / 非对象 $not 全被静默吞掉,且它的算子拒收没有 ADR-0112 信封 #5346

Description

@os-zhuang

#5324 / #5328 时把 driver-memory 的 normalizeFilterCondition 与 driver-mongodb 的 translateFilter 逐 arm 对读(后者是前者 $not$nor 改写的先例),发现 mongodb 侧带着同一批「该拒收没拒收」的 arm。按 Prime Directive #10 单独记在这里,unassigned。

位置

packages/plugins/driver-mongodb/src/mongodb-filter.ts,translateCondition(:96)与 translateFieldOperators(:170)。

三条静默吞掉 + 一条信封缺失

1. $between 形状错误 —— 与 #5328 逐字同款

case '$between':
  if (Array.isArray(value) && value.length === 2) {
    result.$gte = store(value[0]);
    
  }
  break;               // ← 形状不对时什么都不写,整条约束消失

这是 #5328 在 driver-memory 上修掉的那段代码的孪生。同一输入 { score: { $between: 5 } }:

后端 行为
driver-sql INVALID_FILTER / 400 —— Operator "$between" on field "score" requires a [min, max] value array.(实测)
driver-memory INVALID_FILTER / 400(#5328 修复后,措辞与 SQL 首句逐字一致)
driver-mongodb 不抛,字段归一化成 {},交给 MongoDB → 结构相等比较

2. $and / $or 非数组、$not 非对象 —— 整条组合子消失

case '$and':
  if (Array.isArray(value)) {  }
  break;               // 非数组 → 什么都不写
case '$not':
  if (value && typeof value === 'object') {  }
  break;               // 非对象 → 什么都不写

一个组合子写坏了不报错,而是不产生任何谓词 —— 在 $and 位置上等于「匹配全表」,方向是放大。driver-sql 的 assertFilterNodeList / assertFilterNode(#5134)与 driver-memory 现在的 shape gate(#5324)都拒收这些。

3. 未知算子拒收了,但丢了信封

default:
  throw new Error(`[mongodb] unsupported filter operator '${op}'`);

拒收本身是对的(注释还写明了 $where / $function 的 P0 理由,值得保留)。缺的是拒收的身份:

另外 translateConditiondefault 分支会跳过 ['limit','offset','fields','orderBy'] 四个 key —— 这是把查询级字段混进 where 的历史兜底,QueryASTSchema.whereFilterConditionSchema,不该有这四个 key;顺带一并看。

建议(不代裁决)

四家后端里三家已经统一到「无法编译 → INVALID_FILTER / 400 + 位置信息」,mongodb 补齐即可:

  • 建一个与 driver-sql / driver-memory 孪生的 filter-refusal.ts(两边现有实现逐字可抄),unsupportedFilterErrorINVALID_FILTER / 400、不带包名前缀;
  • $between 补 else 抛错,措辞用 driver-sql 的首句 Operator "$between" on field "…" requires a [min, max] value array.;
  • 组合子操作数补 assertFilterNode / assertFilterNodeList;
  • default 的现有 throw 换成带信封的版本。

未验证的部分

没有跑 driver-mongodb 的测试套件(它需要真实 mongod / mongodb-memory-server,本地未起),以上全部来自逐行代码对读,不是实测。mongodb-filter-logic-conformance.test.ts 是否会因为这些改动变红也未验证。请实现方先实测再动手。

关联:#5328(driver-memory 的 $between 同款,已修)、#5324(未知算子逃出信封,已修)、#5134(driver-sql 的组合子形状门)、#4436 / #5240(信封统一)、#3867(消息前缀不外泄)、#4405(mongodb 的 $not$nor 翻译)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions