Skip to content

/analytics/sql 回显的 SQL 丢掉 $startsWith / $endsWith 谓词:回显比实际执行的查询更宽,无法复现结果 #5333

Description

@os-zhuang

#5325 时给第三个编译器(ObjectQLStrategy.renderFilterNodeSql,即回显给浏览器的展示
SQL)补布尔常量 kind,顺手核对它的算子覆盖面,发现这一条。不属于 #5325 的范围面,
按 Prime Directive #10 单独记在这里,unassigned。

位置

packages/services/service-analytics/src/strategies/objectql-strategy.ts
buildFilterClauseSql / SCALAR_SQL_OPS

现象(实测)

buildFilterClauseSql 显式处理 set / notSet / in / notIn / contains /
notContains,其余落到

const op = SCALAR_SQL_OPS[operator];   // { equals, notEquals, gt, gte, lt, lte }
if (!op) return null;                  // ← 静默丢掉整条谓词

startsWith / endsWith 既不在 SCALAR_SQL_OPS 里,也不在上面的分支里,于是返回 null,
被调用方当作「这个节点没有约束」丢掉。同一个 query 走 NativeSQLStrategy 时是有谓词的:

where NativeSQLStrategy.generateSql(真正执行的) ObjectQLStrategy.generateSql(回显的)
{ stage: { $startsWith: 'w' } } WHERE stage LIKE $1,['w%'] 没有 WHERE,params 为空
{ stage: { $endsWith: 'n' } } WHERE stage LIKE $1,['%n'] 没有 WHERE,params 为空
{ stage: { $contains: 'w' } } WHERE stage LIKE $1 WHERE stage LIKE $1

为什么是 bug

这个字符串的存在理由就是复现执行objectql-strategy.ts 自己在渲染块顶上写着:

a rendering that contradicts execution is worse than no rendering

以及后来补 $or / 时间窗口时那句「omitting it here would be the lie in the other direction」。
一个作者带着「为什么这张图少了几行」来看回显,拿到的是一条没有该筛选条件的语句 ——
跑一遍返回更多行,于是结论是「筛选器没生效」,而实际执行是生效的。这与 #3601 / #3602 /
#3650 修的是同一类「回显与执行不一致」。

不涉及越权或错行:该字符串从不执行(execute() 的 echo 会丢弃 params),
损害限于可调试性。

建议

startsWith / endsWith 补进 buildFilterClauseSql(与 contains 同一分支,
pattern 分别是 `${v}%` / `%${v}`,与 NativeSQLStrategy.buildFilterClause
likePattern 表一致)。

更根本的一条:return null 这个「渲染不了就静默丢」的出口本身是缺陷形状 —— 与
filter-normalizer.ts 对未知算子直接 THROW 的姿态相反。normalizer 的算子词汇表是
封闭的(不支持的算子在那里就抛了),所以回显端遇到映射不到的算子只可能意味着两张表
漂移了,抛错比静默丢更符合这个文件其它地方的立场(参考 convertFilterdefault: 分支,
它正是为同一个理由从「当成等值」改成抛错的,#4128)。

关联:#5325(同函数、同一轮里发现)、#4128(同类「算子静默丢失」)、#3602 / #3650
(回显必须忠实于执行)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions