Skip to content

JS 求值面全体拒收 $icontains(driver-memory 两面 / driver-mongodb / objectql having / formula)—— SQL 族已实现,同一 filter 在内存 double 上抛错 #6520

Description

@os-zhuang

Part of #4706。从 #5702 实施期实测拆出:#5702SQL 族(driver-sql / driver-sqlite-wasm / driver-turso 的 local + remote 两面)实现了 $icontains,JS 求值面一个都没有

现状(实测,#5702 落地后)

{ name: { $icontains: 'acme' } }
driver-sql / -sqlite-wasm / -turso(local+remote) ✅ 求值,ASCII-only 折叠
driver-memory 查询路径 + 分析面 INVALID_FILTER / 400(SUPPORTED_FIELD_OPERATORS 由 spec FILTER_OPERATORS 派生,该表刻意未收 $icontains)
driver-memory 参考匹配器 ❌ 同上(同一道 shape gate)
driver-mongodb default: 拒收
objectql having CONDITION_OPERATORS 不含它
@objectstack/formula matchesFilter ❌(未在 #5702 范围内核过实现,但它不在任何 $icontains 分支里)

拒收是 fail-closed,不是静默放宽 —— 这是刻意的方向,不是缺陷本身。缺陷是同一条 filter 在两类后端上给两个答案:一个返回行,一个抛 400。

用户可见后果

应用测试跑内存 double、生产跑 SQL 是本仓的常见形态(plugin-authauth-contains-filter.test.ts 就是这个形状)。一条用 $icontains 的 filter 会在测试里抛错、在生产里正常,或者反过来 —— 正是 #4706$regex 的原始指控(「the divergence only shows up when the app's tests run on the memory double and production runs SQL」),换了个算子重演。

下游 #5814(better-auth Where.mode: 'insensitive')一旦落地就会踩到:认证查询在内存 double 上会 400。

为什么 #5702 没做

建议范围

  1. packages/specFILTER_OPERATORS 收入 $icontains,同 PR 更新 filter-operator-vocabulary.test.ts 的差集 pin(该 pin 现在钉死差集恰为 { $icontains });
  2. driver-memory 两面 + driver-mongodb 的实现(ASCII-only 折叠,不是 toLowerCase() —— 契约以 FILTER_TEXT_CASES 的非 ASCII 不折 pin 为准);
  3. service-analyticscompileScopedFilterToSql 补一条臂(否则 echo 覆盖测试判红);
  4. objectql having 与 formula 同批;
  5. scripts/check-driver-conformance.mjs 里 driver-memory / driver-mongodb 两行 FILTER_TEXT_CASES DEBT 的 requirement-1 半边。

memory 侧实现本身是平凡的(真正则引擎已在,ASCII 折叠即可);贵的是词表纳入牵动的 allowlist 消费者。

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