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
这一面比 driver-sql 那面更该拒。read-scope-sql 是 RLS / 租户读取范围的下降点,模块自述「Fail-closed. Any operator, value shape, or identifier it cannot translate THROWS. A read-scope predicate must never be silently dropped」。{$exists: "false"} 写来表示「没有 owner 的行」,编出来是「有 owner 的行」—— 这是加宽(admit 了策略要排除的行),不是 fail-closed 的收窄。
信封现成,不需要新设:本模块自述「⛔ The only way this module refuses」就是 READ_SCOPE_COMPILE_FAILED / 500,#6125 的裁决刚刚复用过一次,理由同样适用(read scope 是平台编译产物,不是调用方输入)。措辞可参照 driver-sql 的 nonBooleanNullComparandError / nonBooleanExistsComparandError,注意 #5240「一个条件一种措辞」。
出自 #6125 的实施(PR 见下)。#6125 的裁决把派工严格限定在「比较数位置的
undefined」一格;$null/$exists被有意排除在那次清扫之外(它们的比较数是声明的布尔量,不是比较数位置 ——driver-sql的孪生实现也这样跳过)。排除时顺手实测了这一格,记在此处,按 Prime Directive #10 另立单、不指派、不扩大那张 PR 的 diff。实测(
origin/main@d8e8d9cbc,直接调compileScopedFilterToSql(filter, 't')){owner_id: {$null: true}}"t"."owner_id" IS NULL✅{owner_id: {$null: false}}"t"."owner_id" IS NOT NULL✅{owner_id: {$null: "false"}}"t"."owner_id" IS NULL⛔ 与作者写的意思相反{owner_id: {$null: "true"}}"t"."owner_id" IS NULL{owner_id: {$null: 0}}"t"."owner_id" IS NOT NULL{owner_id: {$null: null}}"t"."owner_id" IS NOT NULL{owner_id: {$exists: "false"}}"t"."owner_id" IS NOT NULL⛔ 与作者写的意思相反{owner_id: {$exists: 0}}"t"."owner_id" IS NULL{owner_id: {$exists: "no"}}"t"."owner_id" IS NOT NULL发射器是
compileOperator里的case '$null': return val ? IS NULL : IS NOT NULL;与case '$exists': return val ? IS NOT NULL : IS NULL;—— 真值性,不是按声明的布尔域。为什么这是缺陷
@objectstack/spec的FieldOperatorsSchema把两者都声明为z.boolean()。 声明 ≠ 强制(PD chore: version packages #10 的原话)。driver-sql已经不这么读了。$null的比较值不是布尔时,driver-sql 与 driver-memory 给出**完全相反**的答案(一个 IS NULL,一个 IS NOT NULL)—— 实测 #5347($null)与$exists的比较值不是布尔时,三个后端面给出三个答案,driver-memory 自己的两个面在'yes'上就已分叉 —— 实测,$null(#5347)的同族另一轴 #5369($exists)在那一面把非布尔比较数改成了拒收,理由逐字适用于此:"false"这个字符串是真值,于是它落在了它被写下来所要表达的false的对面。那两次裁决没有推到本编译器。read-scope-sql是 RLS / 租户读取范围的下降点,模块自述「Fail-closed. Any operator, value shape, or identifier it cannot translate THROWS. A read-scope predicate must never be silently dropped」。{$exists: "false"}写来表示「没有 owner 的行」,编出来是「有 owner 的行」—— 这是加宽(admit 了策略要排除的行),不是 fail-closed 的收窄。触达性(判严重度需要的那一半)
与 #6125 那格有一个关键差别:这个坏形状过得了 JSON。
undefined只能从进程内来,而"false"/0/null是合法 JSON 值,可以躺在库存的sys_metadata里。进料口:
compileScopedFilterToSql的filter来自ctx.getReadScope(objectName),默认桥到plugin-security的getReadFilter→computeRlsFilter,后者从管理员写的 permission set / sharing rule 与 CEL 下降编出来。本单在packages/plugins/plugin-security/src/security-plugin.ts里没找到对这条 filter 的任何 Zod 校验(全文无FilterConditionSchema/safeParse),也就是说这条路径上没有一道把非布尔$null挡下来的闸。$null: "false"—— 规则元数据本身可能只允许特定算子形状,或 CEL 下降根本不发射$null。谁来处置这一格,第一件事应该是把「{$null: <非布尔>}能不能从库存 metadata 走到compileScopedFilterToSql」跑通或证伪;跑通了就不是 observation 级。严重度请分诊自己判(#5347 的先例:立单时的定级两个方向都不可靠 —— #5347 自己那格的「转义细节」后来是个 P0 过滤器绕过)。处置提示(供裁决方,不是既定结论)
信封现成,不需要新设:本模块自述「⛔ The only way this module refuses」就是
READ_SCOPE_COMPILE_FAILED/ 500,#6125 的裁决刚刚复用过一次,理由同样适用(read scope 是平台编译产物,不是调用方输入)。措辞可参照driver-sql的nonBooleanNullComparandError/nonBooleanExistsComparandError,注意 #5240「一个条件一种措辞」。⛔ 顺带提醒:本编译器的
nullValueSatisfiesOperator对$null/$exists用真值性判、而driver-sql的同名表用与false的恒等判 —— 这是有意的(每张极性表钉的是它自己发射器的拼写,#5146 / #5298 的不变量)。发射器若改成按声明拒收,这两张表的对应条目必须同 PR 一起改,否则不变量断在定义处。{$null: undefined}/{$exists: undefined}今天分别编成IS NOT NULL/IS NULL,已在 PR 的read-scope-undefined-comparand.test.ts里作为「本次有意不扫的位置」钉住 —— 本单落地时那两行就是要改的地方。关联
undefined比较数在仓内有五种读法 —— #6050 只在 driver-sql/turso 落了拒收,formula 读作「键缺失」、read-scope-sql 编成= NULL、driver-memory 读作 null #6125(本单的出处;其裁决只覆盖undefined比较数,明确不含$null/$exists)$null的比较值不是布尔时,driver-sql 与 driver-memory 给出**完全相反**的答案(一个 IS NULL,一个 IS NOT NULL)—— 实测 #5347($null非布尔比较数按声明拒收,driver-sql)$exists的比较值不是布尔时,三个后端面给出三个答案,driver-memory 自己的两个面在'yes'上就已分叉 —— 实测,$null(#5347)的同族另一轴 #5369($exists同上)READ_SCOPE_COMPILE_FAILED/ 500 信封)$not的语义在 driver-sql 与 driver-memory / formula 之间分叉:NULL 行的去留相反,$not: {}一个是 TRUE 一个是 FALSE #5146 / 非否定路径上的$ne/$nin/$notContains:driver-sql 排除 NULL 行,driver-memory / formula 返回它们(#5146 只裁定了$not) #5298(极性表钉自己发射器拼写的不变量)会话:
session_01WyvqvKMG6asi9aXjKE6xtx(#6125 实施过程中发现,未指派)