修 #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 理由,值得保留)。缺的是拒收的身份:
另外 translateCondition 的 default 分支会跳过 ['limit','offset','fields','orderBy'] 四个 key —— 这是把查询级字段混进 where 的历史兜底,QueryASTSchema.where 是 FilterConditionSchema,不该有这四个 key;顺带一并看。
建议(不代裁决)
四家后端里三家已经统一到「无法编译 → INVALID_FILTER / 400 + 位置信息」,mongodb 补齐即可:
- 建一个与
driver-sql / driver-memory 孪生的 filter-refusal.ts(两边现有实现逐字可抄),unsupportedFilterError 带 INVALID_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 翻译)。
修 #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 逐字同款这是 #5328 在 driver-memory 上修掉的那段代码的孪生。同一输入
{ score: { $between: 5 } }:INVALID_FILTER/ 400 ——Operator "$between" on field "score" requires a [min, max] value array.(实测)INVALID_FILTER/ 400(#5328 修复后,措辞与 SQL 首句逐字一致){},交给 MongoDB → 结构相等比较2.
$and/$or非数组、$not非对象 —— 整条组合子消失一个组合子写坏了不报错,而是不产生任何谓词 —— 在
$and位置上等于「匹配全表」,方向是放大。driver-sql 的assertFilterNodeList/assertFilterNode(#5134)与 driver-memory 现在的 shape gate(#5324)都拒收这些。3. 未知算子拒收了,但丢了信封
拒收本身是对的(注释还写明了
$where/$function的 P0 理由,值得保留)。缺的是拒收的身份:code,没有status→mapDataError走 default 分支 → 客户端拿到 500 形状的裸{ error }。这正是 data: unsupported-filter-operator refusal ships without error.code and leaks the [sql-driver] prefix #4436 为 driver-sql、{ field: {} }(零个操作符的字段约束)在同仓有三个答案:driver-sql 组合子内 TRUE、顶层抛 INVALID_FILTER、formula/driver-memory FALSE #5240 为 driver-memory 已经补上的那件事,mongodb 是唯一还没补的后端。[mongodb]前缀 —— driver-sql 的unsupportedFilterError注释明确写过这类前缀「is driver-internal wording, and shipping it to clients is exactly what the analytics /query 未做 cube 存在性校验,未注册名直达驱动当表名;且错误路径原样回显驱动 SQL(#3770 同类,另一子系统) #3867 sanitiser exists to stop」,已从 SQL 侧删除。另外
translateCondition的default分支会跳过['limit','offset','fields','orderBy']四个 key —— 这是把查询级字段混进where的历史兜底,QueryASTSchema.where是FilterConditionSchema,不该有这四个 key;顺带一并看。建议(不代裁决)
四家后端里三家已经统一到「无法编译 →
INVALID_FILTER/ 400 + 位置信息」,mongodb 补齐即可:driver-sql/driver-memory孪生的filter-refusal.ts(两边现有实现逐字可抄),unsupportedFilterError带INVALID_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翻译)。