fix(driver-sql): fail-loud on unknown filter operators; real IS NULL / IS NOT NULL; $not (#2704)#2872
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 99 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Contributor
Author
|
范围说明里提到的"让所有驱动统一 fail-loud"的更大改动,已单独开:#2873 |
…/ IS NOT NULL; $not (#2704) The array-format where path forwarded any unrecognised operator straight to Knex; on a null comparand that silently became a whole-table match, so a permission/assignment-scoped list view could leak every row (an is_null / is_empty operator from the client). The object-format path silently degraded an unknown $op to equality and had no $null handling. - Render null predicates as real IS NULL / IS NOT NULL, unified with equals+null; != null -> IS NOT NULL. - Support the full spec operator set + client aliases in both filter shapes, incl. $between / $startsWith / $endsWith / $notContains / $null / $exists and the logical $not (negated sub-condition; CEL !expr scopes compile to it). - LIKE-escape contains/startsWith/endsWith with explicit ESCAPE '\'. - Throw on a genuinely unknown operator in BOTH paths (fail-loud, no leak). - spec: recognise client alias spellings (isnull/is_empty/...) -> $null. Adds sql-driver-null-operators.test.ts (17 cases across both paths). Closes #2704
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2704.
问题
driver-sql 把它不认识的 filter 算子直接原样转发给 Knex。当比较值是
null时,这会静默编译成整表匹配——于是一个按权限/负责人范围过滤的列表视图会把所有行都返回出去(数据泄漏)。触发场景很现实:ObjectUI 客户端对空值筛选发的是is_null/isnull/is_empty这类拼写。具体三个坑:
default分支透传未知算子 →is_null+ null 比较值 → 整表匹配;is_empty→ Knex 直接抛 400。{field:{$op:value}})把未知$op静默降级成相等比较,且完全没有$null处理。field = null在 SQL 里永远渲染不出IS NULL。改动
is_null/isnull/is_empty(及否定式)→IS NULL/IS NOT NULL,与equals+null 语义对齐;!= null→IS NOT NULL。$between/$startsWith/$endsWith/$notContains/$null/$exists,以及逻辑算子$not(取反子条件——CEL!expr的权限 scope 会编成它,driver-mongodb/driver-memory都已实现,driver-sql 此前是缺的)。contains/startsWith/endsWith的值做 LIKE 转义并显式ESCAPE '\',防止用户输入里的%/_扩大匹配范围。@objectstack/spec:VALID_AST_OPERATORS/AST_OPERATOR_MAP识别客户端别名拼写并映射到$null,保证数组-AST → 对象-filter 转换与驱动一致。顺带修掉的潜在 bug:CEL 派生的
$startsWith/$endsWith/$null范围过滤(此前对 SQL 静默错误)、better-auth$regexcontains(此前退化成精确匹配)。测试
新增
sql-driver-null-operators.test.ts(17 个用例,覆盖两条路径的空值算子、!=+null、$not、$startsWith、$regex、未知算子抛错、count 范围正确)。范围说明
本 PR 只覆盖 SQL 驱动。理想上"未知算子就报错"应在
parseFilterAST边界统一做,但 objectql 引擎目前把ast.where原样透传给驱动、绕过了parseFilterAST,所以驱动层是当前唯一能拦截的地方。让所有驱动统一 fail-loud 是一个更大的独立改动,单独开 issue 跟踪。