Skip to content

A scalar data.id beside a NON-scalar where.id still silently drops the predicate — the remaining silent shape after the #11142 refusal, pinned by #5748 #11230

Description

@os-zhuang

Found while implementing #11142 (the unequal-scalar where.id refusal). Filed separately and unassigned: acting on it would reverse another #5748-pinned verdict (a SCALAR data.id still outranks where and multi), which is a maintainer decision, not a rider on that card — the same reason #11142 itself was filed off #11009.

The shape

awaitengine.update(obj,{id: 'rec_1',title: 'x'},{where: {id: {$in: ['a','b']}},multi: true});

resolveEngineUpdateDispatch rules by-id with the payload id bound (rec_1): the truthy scalar data.id outranks where and multi alike (#5748 ruling A, pinned in engine-update-dispatch.test.tsa SCALAR data.id still outranks where and multi, first assertion). The $in predicate over ids — and the declared multi: true — are silently discarded. Same for an array or nullwhere.id beside a scalar payload id.

Why #11142 did not cover it

#11142's ruling scoped the refusal to a truthy scalarwhere.id different from the payload id ("truthy scalar where.id 响亮拒绝"), and its PR pins the non-scalar neighbour explicitly as out of the ruled scope so the refusal cannot creep. #11009's unhonoured-keys refusal does not reach it either: the only where key is id. So after both refusals land, this is the lastwhere.id-shaped declaration the by-id update path drops with no diagnostic.

What a fix has to decide

  1. Refuse a payload-sourced by-id dispatch whose where.id is a non-scalar predicate (same loud-refusal family). Reverses the remaining half of the ObjectQL.update 的 data.id 不做标量测试 —— 载荷里的算子对象被当成主键绑定,且盖过显式 options.multi: true #5748 pin — needs a ruling.
  2. Leave it, on the grounds that a payload id is the row address and a caller that also writes an id-set predicate wrote a contradiction too rare to arm. That keeps one silent shape in a family otherwise made loud (ObjectQL.update 的 data.id 不做标量测试 —— 载荷里的算子对象被当成主键绑定,且盖过显式 options.multi: true #5748 payload operator-objects, A compare-and-set where on a by-id update is silently inert — the extra predicate keys never reach the driver, and SqlHttpOutbox.redeliver's status guard is one of them #11009 extra keys, A scalar data.id beside a DIFFERENT scalar where.id silently drops the where.id predicate — the one unhonoured-predicate shape #11009's refusal deliberately left standing #11142 unequal scalars).

Worth noting for the triage: unlike #11142's shape (which could at least be spelled by folding ingresses), no ingress in this repo constructs this pair — the ingress survey on PR #11229 found the non-scalar where.id production sites (outbox sweeps) never carry a payload id.

Refs: packages/metadata-core/src/engine-update-dispatch.ts (the #11142 boundary comment names this shape as deliberately untouched), #5748, #11009, #11142.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions