Skip to content

analytics 的 getObjectDatasource 报告的是「声明值」而非「有效 datasource」:#5033 的诊断会点错库,#5115 的编译期闸门看不见隐式路由的对象 #5288

Description

@os-zhuang

现象

AnalyticsServiceConfig.getObjectDatasourceplugin.ts 里是这样接出来的:

getObjectDatasource: (objectName: string) = dataEngine()?.getObject?.(objectName)?.datasource,

它读的是对象声明object.datasource。但真正决定这个对象的行落在哪个库的是 ObjectQL.getDriver 的五步解析顺序:

  1. 显式的 object.datasource(且不等于 'default')—— 直接短路;
  2. datasourceMapping 规则;
  3. ADR-0057 §3.6 生命周期分流:lifecycle.classaudit / telemetry / event 的对象,在 telemetry datasource 已注册时路由过去;
  4. 所属 package manifest 的 defaultDatasource;
  5. 全局默认 driver。

也就是说,探针只覆盖第 1 步ObjectSchema.datasource.default('default'),所以一个由 2/3/4 步路由到别处的对象,探针照样回答 'default' —— 而 'default'getDriver 里恰恰表示「没有显式绑定,继续往下查」,不是「主库」。

今天就能碰到的后果

(a) #5033 的查询期诊断会点错库。 analytics-service.ts 的 missing-source 分诊用这个探针拼错误文案:

table "X" is not on datasource "Y", which is where its base object "B" lives

sys_audit_log —— 也就是 #5033 那条 issue 的主角 —— 是靠 lifecycle.class: 'audit' 被分流到 telemetry 的,不是靠显式字段。于是这句话会说它在 datasource "default"(或「the default datasource」),把读的人指向一个它根本不在的库。文案的意义就是「点名真实原因」,这里点名的是错的。

(b) #5115 的编译期闸门覆盖不到隐式路由的对象。 #5115(PR #5287)在编译期拒绝跨 datasource 的 join,判据只能收窄到「双方都显式声明了 datasource 且不同」—— 因为把 'default' 当成主库会误拒那些被 mapping 规则落到同一个库的 dataset(误拒 = 升级后看板变白)。结果是:催生 #5115 的那个真实场景(audit 对象靠生命周期分流跨库)对该闸门是不可见的。

建议方向(未实现,留给分诊)

在引擎侧补一个权威的「对象的有效 datasource 名字」访问器 —— 相当于把 getDriver 的解析顺序抽出来只算名字、不取 driver,然后让 plugin.ts 的探针改接它。resolveMappedDatasource(#4462)已经为「不要在别处重写一遍路由规则」开了先例,datasource-connection-service 里也明确写着第二份实现必然漂移 —— 同样的理由适用于这里:analytics 侧不应该自己重算生命周期分流和 package 默认值。

补上之后:

注意

改动落点大概率是 packages/objectql/src/engine.ts,该文件目前有在飞单(#5272),排期时留意冲突面。

出处:实现 #5115 时观察到(PR #5287),该 PR 已把这条限制写进代码注释、changeset 与 PR 正文,行为上以「证明不了就不拒绝」的方式规避,不依赖本单。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions