Skip to content

driver-memory analytics 面的 generateSqlcontains 回显成 LIKE 'et'(没有 % 通配符)—— 回显的是等值匹配,执行的是子串匹配 #5444

Description

@os-zhuang

#5374(mingo 出口的 $notContains 编译成裸 {$not: 'x'})时,顺手把同一个 wheregenerateSql 出口的回显也测了。这一条不属于 #5374 的范围面 —— 那一条在 mingo 出口,这一条在 SQL 回显出口,#5374 修好之后完整存在。

作为 #5433 的 sub-issue 而不是独立 issue,因为修复落点完全在 #5433 的完成范围之内:同一个 operatorToSql 映射表 + 同一个 generateSql 的 WHERE 构建循环。分开修会让同一个函数被改两次。unassigned。

位置

packages/plugins/driver-memory/src/memory-analytics.ts:

  • operatorToSql(约 :800)—— 'contains': 'LIKE''notContains': 'NOT LIKE';
  • generateSql 的 WHERE 构建循环(约 :450)—— 把比较数原样交给 toSqlLiteral,不加通配符。

现象(实测)

3 行数据,name 分别为 alpha / beta / gamma(只有 betaet):

wherequery() 取到generateSql() 输出的 WHERE该 SQL 若执行会取到
{name: {$contains: 'et'}}[2](正确)WHERE name LIKE 'et'0 行
{name: {$notContains: 'et'}}[1,3](#5374 修复后正确)WHERE name NOT LIKE 'et'3 行

SQL 的 LIKE 'et' 没有 %,语义是等值匹配(等价于 = 'et'),不是子串匹配。正确的回显应当是 LIKE '%et%' / NOT LIKE '%et%',比较数里的 %_ 还需要转义(否则作者写的 50% 会变成通配符)。

为什么是 bug

  1. 回显的用途就是让作者看懂自己问了什么。generateSqlIAnalyticsService 的公开方法,其返回值也是 AnalyticsResult.sql 承诺的「生成的 SQL」。一个把「包含 et」显示成「等于 et」的 SQL,恰恰在作者最需要它说实话的时候说了假话 —— 与 /analytics/sql 回显的 SQL 丢掉 $startsWith / $endsWith 谓词:回显比实际执行的查询更宽,无法复现结果 #5333 同类,只是那一条是谓词整个丢掉,这一条是谓词还在但含义变了。
  2. 两个出口对同一个 where 给出不同含义,{ field: {} }(零个操作符的字段约束)在同仓有三个答案:driver-sql 组合子内 TRUE、顶层抛 INVALID_FILTER、formula/driver-memory FALSE #5240 为本包立下的不变量所禁止的形状,与 driver-memory analytics 面的 generateSqlin/notIn/set/notSet 输出错误 SQL:回退成 = 且只取第一个值($in: ['100','200']WHERE code = '100') #5433 正文里 in/notIn/set 那三条并列。
  3. 大小写这一半是巧合对上的。 mingo 出口是 /…/i(driver-memory analytics 面的 $notContains 编译成裸 mingo {$not: 'x'},该谓词不约束任何行 —— 结果被放大到全表 #5374 起借用 driver 自己的 filterSubstringPattern),而 SQLite 的 LIKE 对 ASCII 默认就不区分大小写 —— 所以这一维恰好一致,但那是两个互不相干的默认值碰巧撞上,不是任何人写下的约定。修 % 的时候值得顺便把它写成约定。

未验证的部分

关联:父 issue #5433(同函数、同一映射表)、#5374(同一 where 的另一个出口)、#5333(回显与执行不一致)、#5240

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