Skip to content

update 的 **by-id** 路径同样把非标量 data.id 交给驱动写主键列(#6262 的孪生形状,where.id 胜出时) #6435

Description

@baozhoutao

范围外发现,来自 #6262 / PR #6433 的实施过程(PD #10)。#6262 与其分诊都把范围钉在 multi 分支(「Scope as queued = route A only」、「非 multi 路径不动」),所以本条未在该 PR 内修改,只记录。

事实

#6262 收口的是 multi 分支的 SET 载荷。同一个缺陷在 by-id 分支上还留着一份,触发条件是 data.id 非标量、而 options.where.id 是标量真值 —— 也就是 ENGINE_UPDATE_DISPATCH_CASES 自己列着的那一行:

{ what: 'operator object in data.id, scalar where.id — the WHERE id wins, the operator is not one',
  data: { id: { $in: ['a', 'b'] }, title: 'x' },
  options: { where: { id: 'rec_1' } },
  expect: 'by-id', expectId: 'rec_1' }

派发是对的(#5748 裁 A / PR #5919:算子对象不是 id,where.id 胜出,绑定 rec_1),但载荷同样没被清理。实测(PR #6433 新增测试里对现状的钉死断言,绿):

driver.update('task', 'rec_1', { id: { $in: ['a','b'] }, title: 'x' })
                                 ^^^^^^^^^^^^^^^^^^^^^^ 进 SET 子句

驱动侧确认这确实落到 SET 而非被忽略 —— packages/drivers/driver-sql/src/sql-driver.ts:3254update():

const builder = this.getBuilder(object, options).where('id', id);
const formatted = this.applyWriteColumnMap(object, this.formatInput(object, data));
await builder.update(formatted);

formatted整个 data 得出,id 不在任何跳过名单里。于是 SQL 形如 UPDATE task SET id = '{"$in":["a","b"]}', title = 'x' WHERE id = 'rec_1' —— rec_1 的主键被改写成一个序列化的算子对象。

#6262 的关系

同一族、不同分支,不是重复:

行定位 载荷里的 id 状态
#6262 where 谓词(AST) 算子对象等 ⇒ 已剥离(PR #6433) 已修
本条 driver.update 的独立 id 参数 算子对象等 ⇒ 仍原样进 SET 未修

PR #6433 的注释与测试对 by-id 路径的说法是「主键走独立参数,载荷里的 id 是冗余而非破坏」—— 那句话对标量 data.id 成立(SET id = 'rec_1' WHERE id = 'rec_1',同值空写),对非标量不成立,这就是本条。该 PR 已按现状把 by-id 载荷钉死,所以本条一旦修,那两个 pin 会响亮翻红,不会被悄悄改掉。

另一个更常见的入口

同样的判定阶梯下,data: { id: null, … } + 标量 where.id 也走 by-id,SET 里就带上 id = NULL:客户端 GET 一条记录、改两个字段、整体 PUT 回来,而序列化把 id 写成 null 的形状,就够了。落到 SQL 是 NOT NULL 约束报错(好的情况),或在宽松存储上留下一条主键为空的行。未实测这条端到端(REST 层是否先行剥 id 没有查),只记录形状,严重度请分诊裁。

方向(不预设结论)

关联:#6262 / PR #6433(multi 分支那一半)、#5748 / PR #5919(data.id 的标量判定)、#5922(id 之外的标量面)、#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