修 #5325 时把 worktree 同步到含 #5329 (#5158 拍板 C 第 2 步)的 origin/main,核对本次改动
是否与之冲突,发现 analytics 这条路径不在那一单的门面清单里。不属于 #5325 的范围面 ,
按 Prime Directive #10 单独记在这里,unassigned。
位置
packages/services/service-analytics/src/strategies/filter-normalizer.ts 的
normalizeAnalyticsFilterTree:
const where = ( query as { where ?: unknown } ) . where ;
if ( ! where || typeof where !== 'object' || Array . isArray ( where ) ) return null ;
Array.isArray(where) → return null —— 整条 where 消失 ,不报错,不留痕。
现象(实测)
NativeSQLStrategy.generateSql({ cube:'deals', measures:['total'], dimensions:['id'], where: [{ stage: 'won' }] }) 生成:
SELECT id AS "id", COUNT(*) AS "total" FROM "deal" GROUP BY id -- 没有 WHERE
params 为空。作者写了筛选,图上画的是整个数据集 —— #3650 / #4128 反复付过学费的那一类
静默放宽,只是入口换成了数组写法。
为什么现在值得单独记
#5329 (#5158 拍板 C 第 2 步)刚刚把 FilterArray 定成 INPUT-ONLY 的编写期糖 ,并让
engine 的六个入口(find/findOne/count/aggregate/update/delete)统一走
isFilterAST → parseFilterAST 下沉,四个驱动的数组方言删除、改成响亮的
INVALID_FILTER / 400;cloud 的 RemoteTransport.buildWhereSQL 自 cloud#1075 起也是拒收。
那一单的结论是「一个 query 在哪条路上都只有一个答案」。
analytics 是第五道门 :它自己就把 where 编译成 SQL(NativeSQLStrategy)或
FilterCondition(ObjectQLStrategy),不经过 engine 的那道下沉。今天它给的是三个可能答案
里最差的那个 —— 既不是 lower(照 parseFilterAST 解释),也不是 refuse(响亮 400),
而是静默丢弃 。
两条路都行,需要拍板
Lower —— 与 fix(objectql,driver-sql,driver-memory,driver-mongodb)!: FilterArray 在 engine 门下沉,四驱动数组方言删除 (#5158 拍板 C 第 2 步) #5329 的 engine 入口一致:isFilterAST(where) 就先 parseFilterAST
再交给 buildNode。作者用哪种写法都得到同一份行集,与「FilterArray 是编写期糖」
的定性完全吻合。代价是 service-analytics 目前只依赖 @objectstack/core +
@objectstack/spec,要看 parseFilterAST 住在哪个包、会不会带进新依赖。
Refuse —— 与四个驱动删除数组方言后的姿态一致,抛错而不是静默丢。实现最省,
且分析查询的 where 通常由 dashboard metadata 提供,编写期炸掉比运行期多画几万行好。
个人倾向 1(lower) :#5158 的拍板 C 说的就是「在门口下沉」,analytics 只是当时没被点到
的一道门;拒收会让同一份 dashboard metadata 在普通 find() 上能跑、在图表上报错。
但这是契约位置的选择,不该由实现顺手定。
未验证
没有找到今天真的会给 analytics 传数组 where 的 producer(dashboard widget 的 filter
走 FilterCondition 对象形状);这条是面 的漏洞,不一定有现网触发。严重度请 PM 按 triage
定,不代表我判断它低 —— #5158 那条路上的同类问题一开始也没有已知 producer。
关联:#5158 (拍板 C)、#5329 (第 2 步,engine 六入口下沉 + 四驱动删方言)、
cloud#1075(transport 侧早已拒收)、#5325 (同函数、同一轮里发现)、#3650 / #4128
(同类「谓词静默消失 → 画全表」)。
修 #5325 时把 worktree 同步到含 #5329(#5158 拍板 C 第 2 步)的
origin/main,核对本次改动是否与之冲突,发现 analytics 这条路径不在那一单的门面清单里。不属于 #5325 的范围面,
按 Prime Directive #10 单独记在这里,unassigned。
位置
packages/services/service-analytics/src/strategies/filter-normalizer.ts的normalizeAnalyticsFilterTree:Array.isArray(where)→return null—— 整条where消失,不报错,不留痕。现象(实测)
NativeSQLStrategy.generateSql({ cube:'deals', measures:['total'], dimensions:['id'], where: [{ stage: 'won' }] })生成:params为空。作者写了筛选,图上画的是整个数据集 —— #3650 / #4128 反复付过学费的那一类静默放宽,只是入口换成了数组写法。
为什么现在值得单独记
#5329(#5158 拍板 C 第 2 步)刚刚把
FilterArray定成 INPUT-ONLY 的编写期糖,并让engine 的六个入口(
find/findOne/count/aggregate/update/delete)统一走isFilterAST→parseFilterAST下沉,四个驱动的数组方言删除、改成响亮的INVALID_FILTER/ 400;cloud 的RemoteTransport.buildWhereSQL自 cloud#1075 起也是拒收。那一单的结论是「一个 query 在哪条路上都只有一个答案」。
analytics 是第五道门:它自己就把
where编译成 SQL(NativeSQLStrategy)或FilterCondition(ObjectQLStrategy),不经过 engine 的那道下沉。今天它给的是三个可能答案里最差的那个 —— 既不是 lower(照
parseFilterAST解释),也不是 refuse(响亮 400),而是静默丢弃。
两条路都行,需要拍板
FilterArray在 engine 门下沉,四驱动数组方言删除 (#5158 拍板 C 第 2 步) #5329 的 engine 入口一致:isFilterAST(where)就先parseFilterAST再交给
buildNode。作者用哪种写法都得到同一份行集,与「FilterArray 是编写期糖」的定性完全吻合。代价是
service-analytics目前只依赖@objectstack/core+@objectstack/spec,要看parseFilterAST住在哪个包、会不会带进新依赖。且分析查询的
where通常由 dashboard metadata 提供,编写期炸掉比运行期多画几万行好。个人倾向 1(lower):#5158 的拍板 C 说的就是「在门口下沉」,analytics 只是当时没被点到
的一道门;拒收会让同一份 dashboard metadata 在普通
find()上能跑、在图表上报错。但这是契约位置的选择,不该由实现顺手定。
未验证
没有找到今天真的会给 analytics 传数组
where的 producer(dashboard widget 的filter走 FilterCondition 对象形状);这条是面的漏洞,不一定有现网触发。严重度请 PM 按 triage
定,不代表我判断它低 —— #5158 那条路上的同类问题一开始也没有已知 producer。
关联:#5158(拍板 C)、#5329(第 2 步,engine 六入口下沉 + 四驱动删方言)、
cloud#1075(transport 侧早已拒收)、#5325(同函数、同一轮里发现)、#3650 / #4128
(同类「谓词静默消失 → 画全表」)。