Skip to content

data.id 是算子对象 + multi: true 时,{"$in":[...]} 作为普通列进入 updateMany 的 SET 载荷,写向主键列 #6262

Description

@baozhoutao

范围外发现,来自 #5922(PR 见该单)的实现过程。#5922 收口的是声明值为标量的字段上的算子对象;id 不在其中,因为它的归属在另一条轴上,未在该 PR 内修改(PD #10)。

事实(worktree @ origin/main @ 70f132c15,记录型 driver 驱动真实引擎,packages/objectql)

PROBE data.id operator + multi: {"err":null,
  "calls":[{"fn":"updateMany","args":[{"object":"probe_task"},{"id":{"$in":["a","b"]},"title":"x"}]}]}

update('task', { id: { $in: ['a','b'] }, title: 'x' }, { multi: true }) 今天:

为什么 #5922 没顺手收口

record-validator.tsSKIP_FIELDS 按设计跳过 id(引擎自有列),而更重要的是:这一格的裁定已经写在派发层,而不是校验层。ENGINE_UPDATE_DISPATCH_CASES(packages/metadata-core/src/engine-update-dispatch.ts)明确列了这条 case:

operator object in data.id WITH multi:true — the declared bulk intent is honoured (#5748)expect: 'multi'

packages/objectql/src/engine-update-dispatch.test.ts真实引擎逐条驱动这个 case-set。在 record-validator 里拒收同一个调用,就是对同一个问题给出第二个答案 —— 正是 engine-update-dispatch.ts 这一族模块被抽出来防止的事(#4550 / #4434)。所以这条要么由派发层在判定 data.id 不是 id 之后顺手把它从 SET 载荷里剥掉,要么是一次明确的裁决说「带算子对象 data.id 的 multi 调用应当拒绝」—— 两者都在 #5748 / #5919 的轴上,不在字段校验的轴上。

建议方向(不预设结论)

注意 #5591(update 载荷剥离时序,同包待发)可能与 A 落在同一处代码,建议一并定价。

倾向 A。它与 #5748 已裁的语义一致(声明了 bulk intent 就照做),只是把「不是 id 的 data.id」从主键位置移走之后不再把它留在列位置

关联:#5922(母体,id 之外的标量面已收口)、#5748 / PR #5919(裁 A,data.id 的标量判定)、#5591(同包 update 剥离时序)、#4550 / #4434(为什么共享谓词而不是第二个答案)。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions