You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
data: the SQL driver emits the current_user framework token as a literal column DEFAULT, so the database itself writes a non-id into a lookup('sys_user') #4560
}elseif(dv==='current_user'){// When there is no authenticated user (system/anonymous), leave it unset// and let required-validation decide — never stamp a bogus owner.if(execCtx?.userId!=null)out[f.name]=String(execCtx.userId);}
发现自 #4551 的悬空引用巡检在真实启动中的第一次运行(showcase,
pnpm dev -- --fresh -p 38109,PR #4559 分支)。这是巡检报出的唯一一类发现,且它是真的。存进
lookup('sys_user')列的值是字符串current_user—— 框架的 defaultValue 令牌本身,不是任何用户的 id。根因:不是引擎,是 DDL
引擎这一侧是对的。
ObjectQL.applyFieldDefaults(packages/objectql/src/engine.ts:1448)显式处理该令牌,并且在没有登录用户时刻意不落值:值是数据库写的。
SqlDriver建列时把任意非对象defaultValue原样下发为列 DEFAULT(packages/plugins/driver-sql/src/sql-driver.ts:5952):于是引擎故意留空的那一列,被 SQL 的列默认值填成了字面串
'current_user'。注意
'NOW()'就在紧邻的上一个分支里被翻译成了驱动原生默认值,理由写得很清楚——「而不是把字面串'NOW()'留给碰巧写入的上游代码」。current_user是同一个约定家族的成员,只是从来没被同样处理。为什么 #4441 抓不到
#4441 的引用完整性校验只看调用方给出的值。这里调用方(和引擎)什么都没给,值是数据库自己供的——写入路径根本看不见它,所以既不是豁免也不是漏判,是它天然在检查的定义域之外。这也正是为什么它只能被一条事后巡检发现。
复现
字段定义:
examples/app-showcase/src/data/objects/field-zoo.object.ts:120种子(
examples/app-showcase/src/data/seed/index.ts:268起)没有设置f_owner,两条 specimen 行因此都吃到了列默认值 —— 与报文里的 2 条一一对应。不依赖 showcase:任何
Field.user({ defaultValue: 'current_user' })+ SQL 数据源 + 一次不带登录用户的插入(种子重放、包安装、启动期供给)都会复现。影响
lookup列里存了一个不是 id 的值 —— 与sys_metadata_history.recorded_by的哨兵(PR fix(data): 审计锚点归引擎所有,lookup 必须能解析 (#4447, #4441) #4511 记录)同类,但这一条没有任何设计意图,纯粹是令牌泄漏。?expand=f_owner或按 owner 关联的读取都会解析到空。Field.user({ defaultValue: 'current_user' })被用在 owner/审批人一类字段上,这就是一条静默的错误归属。待决策的修法方向(未认领)
最小且与既有约定一致的修法,是在 DDL 侧把
current_user与'NOW()'** 同等对待:它是一个**运行时**令牌,没有任何数据库原生对应物,因此**不应该发出列 DEFAULT**(引擎已经在应用层负责它了)。是否还有别的字符串令牌处在同样位置,值得一并盘一遍——col.defaultTo(dv)` 目前对所有非对象 defaultValue 一视同仁,这个兜底才是真正的口子。范围上这需要动 driver 的 DDL 发出逻辑与既有表的迁移(已建的列带着错误的 DEFAULT),所以不在 #4551 的巡检范围内,单独立此 issue。