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.ts 的 SKIP_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(为什么共享谓词而不是第二个答案)。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions