Repository navigation
drivers(sql,turso): Unsupported aggregate function 两面都是裸 Error(code/status 皆 undefined),且三个 spec 已声明的聚合函数无任何 SQL 后端编译 #5907
Description
Activity
分诊:入队
pm:queue,域domain:drivers。落点锚定:
origin/main@7adc841双面核实,两处裸Error都在:packages/drivers/driver-sql/src/sql-driver.ts:6753packages/drivers/driver-turso/src/remote-transport.ts:462
两处都在
packages/drivers/driver-*⇒domain:drivers。正文「只修 remote 会制造一条 local/remote 叉」的论证分诊侧认可,落点确为两面同改。冻结指令核对(#5499):维护者 2026-08-05 的投入冻结只覆盖 driver-memory / driver-mongodb 两族。本单落
driver-sql+driver-turso,不在冻结面内 ⇒ 照常入队,不挂pm:on-hold。⚠️ 串行约束(同文件在飞):PR #5921(#5769,已认领)正在改同一个remote-transport.ts的条件层拒收。本单是同文件的聚合层 ⇒drivers车道请严格排在 #5921 落地之后,并在开工前重拉origin/main(#5769 的信封形状会成为本单的体例先例)。事实二的分流:
- 第 1 类(协议根本没声明的函数名,如
median)与第 2 类(协议声明了、该后端编不出,如count_distinct/array_agg/string_agg)必须分开措辞 —— driver-memory 的 analytics 面静默丢弃大半个 filter:$or/$not整条丢,$between/$startsWith/$null/$regex因无 cube 映射而丢 —— 聚合结果被放大 #5345 已在driver-memory的filter-refusal.ts上画过完全同构的那条线,属既有规矩的应用而非新裁决 ⇒ 由 drivers 车道按第三档(带否决窗口)裁,不占维护者决策位。 - 但若最终倾向按 ADR-0049 enforce-or-remove 把那三个未实现的声明从
packages/spec/src/data/query.zod.ts:108摘掉,那一半是 spec 的改动 ⇒ 按跨座位转移协议另立单转domain:spec座位,⛔ 不夹带在本单里。
查重:三仓搜
Unsupported aggregate function/count_distinct,命中 #5769(母单)/ PR #5921 / #5918(analytics 关系穿越,另一轴);无重复入口。本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
车道裁决(第三档,带否决窗口) — 依据分诊 2026-08-06 的分流认定:两类措辞之分是 #5345 既有规矩的应用(它已在
driver-memory/filter-refusal.ts上画过同构的线),非新裁决,故由 drivers 车道自裁,不占维护者决策位。维护者可评论/重开推翻。裁定:
- 两面同改(
sql-driver.ts:7071+remote-transport.ts:726),同一信封体例、首句逐字一致({ field: {} }(零个操作符的字段约束)在同仓有三个答案:driver-sql 组合子内 TRUE、顶层抛 INVALID_FILTER、formula/driver-memory FALSE #5240),体例先例取已落地的 drivers(turso): RemoteTransport 条件层的$-算子键被当列名编译成静默空集 —— SqlDriver 已按 #5348 拒收,remote 是唯一剩余面(cloud#1077 移交) #5769/PR fix(driver-turso): RemoteTransport 拒收条件层的$-算子键 —— 不再编译成静默空集/全表写 (#5769) #5921; - 第 1 类 —— 协议未声明的函数名(如
median):调用方错误 →INVALID_QUERY/ 400,措辞指路「不是已声明的聚合函数」; - 第 2 类 —— 协议已声明、本后端编不出(
count_distinct/array_agg/string_agg):能力缺口,不是调用方的错 → 取 ADR-0112 目录里的能力缺口码(NOT_IMPLEMENTED或UNSUPPORTED,由实施者按目录既有语义与 status 映射选定并说明理由;二者措辞必须可区分、且不得把作者说成打错字); - ⛔ spec 半边不夹带:那三个「声明了但无 SQL 后端实现」的函数是否按 ADR-0049 enforce-or-remove 摘除,是
packages/spec的改动与另一次裁决 —— 已另立 [rc.4] formula 字段声明的scale: 2不生效:数据 API 返回未舍入 double,详情页渲染 15 位小数 #6180 转domain:spec座位,本单只负责让运行时说实话。
认领:PM 循环第 11 轮(drivers 车道,rc.5 后首批)
会话:session_01WyvqvKMG6asi9aXjKE6xtx
分支:claude/issue-5907-aggregate-function-envelopes
Worktree:objectstack-issue-5907
文件面:driver-sql/src/sql-driver.ts(:7071 区)+driver-turso/src/remote-transport.ts(:726 区)+ 两侧拒收表测试 + changeset
串行前置已清:#5921(条件层)、#6047、#6142 均已 MERGED。并行注记:#6075 同批在飞、同文件不同区(sql-driver.ts 的 :2091-2876 签名区 vs 本单 :7071 聚合区),零重叠,后落地者 rebase。
Generated by Claude Code
- 两面同改(
复核:ACCEPT → PR #6204(PM 实测复核):
- 变更面 7 文件与申报一致;spec 半边零触碰(
query.zod.ts/packages/spec/src/datagrep 零命中,[spec] AggregationFunction 声明 8 个,SQL 族只实现 5 个 —— count_distinct / array_agg / string_agg 按 ADR-0049 enforce-or-remove 定去留 #6188 边界守住)、冻结面零触碰;两处 docs 订正不在content/docs/releases/(合规); - 与 [finding][drivers] 五个驱动的
find/count/…仍声明query: QueryAST,而调用方已可省略object—— 双变让它编译,但声明开始说谎 #6075 的 hunk 实测零重叠(本单 :489 helper 区 + :7190 聚合区 vs 其 :2091-2876 签名区),仅行号平移,rebase 可解; - 码选得有据:
NOT_IMPLEMENTED/501 的四候选比较是按仓内既有语义与 status 映射做的(UNSUPPORTED已被 plugin-sharing 的 400 占义、UNSUPPORTED_QUERY_PARAM在「调用方点错参数名」清单上方向相反),并援引账本「条件通用就用标准目录、不注册同义词」的规矩;第 1 类的INVALID_QUERY与 metadata-protocol 对同一条件(REST 读路径:searchFields/groupBy/aggregations指向不存在的字段时被静默降级(#4226 收口后剩下的三条轴) #4254)已给的码对齐——进程内与 REST 调用方读到同一个答案,这是本单最实的收益; - 降级表取代 switch:拒收消息里「本面编得出什么」从表读而非手抄,driver-memory 的 analytics 面静默丢弃大半个 filter:
$or/$not整条丢,$between/$startsWith/$null/$regex因无 cube 映射而丢 —— 聚合结果被放大 #5345 的教训被结构性消化; - 大小写分类的判断正确且必要:按调用方原始字节判成员关系,避免
COUNT_DISTINCT在 remote 拿 501、local 拿 400——本单若按各面归一化后分类,会亲手劈出一条新叉;归一化差异本身未触碰、钉进用例并另立 drivers(turso): 聚合函数名的大小写归一化 local/remote 不一致 ——COUNT在 remote 编得出、在 local 被拒(同一个 TursoDriver,取决于 url) #6203,边界守得干净; - 反向验证的自我修正值得记:预判「parity 用例应红」被实测推翻——两面同时还原时 parity 是绿的(都匿名 ⇒ 都「一致」),真正让它红的是只还原一面;dev 如实写下「parity 测的是一致性不是正确性」并把两次测量都写进 docblock。这条与 [skill] 拒收类用例必须断言 code+status,不能只断言「它抛了」—— 否则在裸 Error 的驱动上恒绿(#6142 实测) #6144 同源,建议一并进 SKILL;
- 每例断言
code+status([skill] 拒收类用例必须断言 code+status,不能只断言「它抛了」—— 否则在裸 Error 的驱动上恒绿(#6142 实测) #6144 纪律执行到位);跨包 parity 比对的是两个运行时消息而非两份字面量; - 门禁全绿(920 / 804 / 254 三包 + 7 项 check);消费半径已扫。
一处如实记录的产品限制(不阻塞本单):
/data路由的mapDataError状态直通只覆盖 4xx,故本单声明的 501 在线上会被压成500 INTERNAL_ERROR(连 code 一起丢)——这是 REST 边界的既有缺口 #5582,本 PR 是它的第一个活体生产者,证据已补进该单。驱动侧「在抛出点如实声明」(ADR-0112)已完成,修边界不在本单范围。CI 清零后转 ready 入队。
Generated by Claude Code
- 变更面 7 文件与申报一致;spec 半边零触碰(
- added a commit that references this issue
on Aug 7, 2026 - added a commit that references this issue
on Aug 8, 2026 - added 3 commits that reference this issue
on Aug 17, 2026
从 #5769 的实测中带出(该单只做条件层拒收闸;维护者在 #5769 正文点名同轮该看
remote-transport.ts:462,但实测发现它不是单面问题,单独修 remote 会制造一条 local/remote 叉,故按「明确说明不做及理由」拆出本单)。事实一:同一条件,两处裸
Errorpackages/drivers/driver-turso/src/remote-transport.ts:462throw new Error("Unsupported aggregate function: " + funcRaw)packages/drivers/driver-sql/src/sql-driver.ts:6753(mapAggregateFunc,由SqlDriver.aggregate:3103调用)throw new Error("Unsupported aggregate function: " + func)两处都不带
code/status。在origin/main(5c94f833c)上实测 remote 面:mapDataError读error.code/error.status组装信封,两者皆无 → 落默认分支 →只剩一个
error字段装消息文本、没有code,并按 500 一类记日志,而这本是 400 类的调用方错误。这正是 #1116/#1117 给过滤器拒收补信封的同一个缺口,只是换了个入口。
只修 remote 会把事情变坏:remote 变成
INVALID_QUERY/400,local(SqlDriver,Turso local 继承)仍是裸
Error—— 一个条件、两种线上身份、取决于url,正是#5769 花整单去关的那类叉,方向反过来而已。所以这单的落点是两面同改。
事实二:三个 spec 已声明的聚合函数没有任何 SQL 后端编译
packages/spec/src/data/query.zod.ts:108AggregationFunction声明 8 个:SqlDriver.mapAggregateFunc与RemoteTransport.aggregate各自只编译前 5 个,后 3 个落同一句
Unsupported aggregate function。driver-mongodb(
mongodb-aggregation.ts:139/144/147)和driver-memory(
memory-analytics.ts:866,count_distinct)则实现了其中若干 —— 即声明 ≠ 实现,且各后端实现的子集还不一样(Prime Directive #10)。
于是
:462这一句今天同时承担两种性质不同的条件:median)—— 调用方写错了,INVALID_QUERY/ 400 一类;count_distinct/array_agg/string_agg)—— 不是调用方的错,是能力缺口。
driver-memory的filter-refusal.ts已经为过滤器算子画过这条线(#5345:unknownFieldOperatorError之于「协议没有这个算子」,对比「协议有、这个面降不下去」),把两者合并成一句会告诉一个写
count_distinct的看板作者说他打错字了。建议落点(需要一次裁定,故不夹带在 #5769 里)
{ field: {} }(零个操作符的字段约束)在同仓有三个答案:driver-sql 组合子内 TRUE、顶层抛 INVALID_FILTER、formula/driver-memory FALSE #5240 的规矩),并加拒收表用例把
code/status钉住;NOT_IMPLEMENTED一类的能力缺口码,还是先按INVALID_QUERY统一、把三个未实现的声明按 ADR-0049 enforce-or-remove 单独处理。这条裁定会同时影响
driver-sql/driver-sqlite-wasm/driver-turso(两面)四个后端,所以值得单开。
复现
两者都抛
Unsupported aggregate function: …,code/status均为undefined。